How to Implement Yes/No Instead of Boolean for Certain Cases in Rails

How to implement Yes/No instead of Boolean for certain cases in Rails?

Locales

I recommend using Rails locales. These enable you to define language text for any of your variables. For example, your app can say "Yes"/"No" for English speakers, and "Oui"/"Non" for French speakers.

Locales are also fast, flexible, and easy to change because they are independent of your typical source code. You can see how locales will lead to very good separation between your source code logic versus the text that you render.

Example:

#./config/locales/en.yml
en:
TrueClass: "Yes"
FalseClass: "No"

#./app/views/items/index.html.erb
The value is <%= translate(myboolean.class) %>
The translate method can be abbreviated like this <%= t myboolean.class %>

Helpers

You will likely see other people coding it like this using a helper:

#./app/helpers/application.rb
def yesno(x)
x ? "Yes" : "No"
end

# ./app/views/items/index.html.erb
<%= yesno(myboolean) %>

Or like this using a constant:

#./app/helpers/application.rb
YESNO = {true: "Yes", false: "No"}

# ./app/views/items/index.html.erb
<%= YESNO[myboolean] %>

These are both quick-and-dirty PHP-like solutions. There are better ways to do it.

Monkey Patching

You asked about this question: Rails (or Ruby): Yes/No instead of True/False.

# ./app/lib/extensions/true_class.rb
class TrueClass
def yesno
"Yes"
end
end

# ./app/views/items/index.html.erb
<%= myboolean.yesno %>

This is called "monkey patching" a Ruby class. In general it's not a good idea for doing what you're trying to do. Why not? Because it breaks an existing Ruby class to force that method into all of your code. This may be OK in rare cases (IMHO) but definitely not for monkey patching view text into a logic class (again IMHO).

How about a migration data type?

You have the right general idea about creating your own migration data type, yet it may be overkill for your case because a boolean is such a typical one-to-one match for a yes/no. When would you want to create your own type? For example if you wanted to store the yes/no using different database primitive types, such as a using a bit flag in one database vs. a string enum in another database.

Decorators

A decorator is a general concept for any app. In Rails, a decorator is a way to add view logic to an existing model or class.

The Rails locales are essentially decorators.

For more advanced needs, there's a good decorator gem called "Draper" which is easy to use. Using decorators tends to help view code be well organized, well namespaced, and easier to test.

Rails (or Ruby): Yes/No instead of True/False

No such built-in helper exists, but it's trivially easy to implement:

class TrueClass
def yesno
"Yes"
end
end

class FalseClass
def yesno
"No"
end
end

Show booleans in Active Admin as 'Yes' and 'No'

Here, this works, it gives you a tick and cross, but appears to be easy to modify.

https://gist.github.com/2574969

You'll need to restart your rails server for this to work, as it modifies the active_admin.rb initialiser.

Of course it creates a class, which is what you want to avoid, but in the absence of anything else, this does work.

Rails model - change true to yes

You can fetch and override the is_value method on the returned records. This would be ok if you are only fetching the records for display purposes and you know that is_value won't be used in any other context.

module TrueToYes
def is_value
super ? "Yes" : "No" # Assuming is_value on MyModel is a boolean
end
end

# For a collection
decorated_models = MyModel.all.map{|model| model.extend(TrueToYes) }
decorated_models.first.is_value # => 'Yes'

# Single Record
my_model = MyModel.first
my_model.is_value # => true
my_model.extend(TrueToYes)
my_model.is_value # => 'Yes'

Replace output of true and false in a view with Rails

<%= @attribute ? 'Yes' : 'No' %>

A nice place to put this might be in the model, so

class Whatever < ActiveRecord::Base
def something_yn
attribute ? 'Yes' : 'No'
end
end

And then in the view:

<%= @instance.something_yn %>

CSV export changing a boolean column from true/false to yes/no

I was able to do this by replacing

d.attributes.values_at(*DataPoint.data_point_columns)

with:

def to_csv(data)
CSV.generate do |csv|
csv << DataPoint.data_point_columns
data.all.each do |d|
percentage = d.percentage ? "Yes" : "No"
csv << [d.id, d.category, d.subcategory, percentage]
end
end
end

def data_point_columns
["id", "category", "subcategory", "percentage"]
end

Rails how to use a select list for a boolean field?

In Rails, false is considered blank. You can try on your rails console:

Sample Image

You should remove the presence validation, and set the field to default to false. Or, since it's a boolean, consider true as true, and false or nil as false.

Displaying boolean values from database in the view with Rails

This can be achieved by using a helper. The first argument after the "?" is the true case; the false case follows the ":".

The example below uses glyphicons, since you mentioned wanting a check mark, but you could insert "Yes" and "No" or any string or html you desire.

def bool_to_glyph(value)
value ? "<span class='glyphicon glyphicon-ok' aria-hidden='true'></span>".html_safe : "<span class='glyphicon glyphicon-remove' aria-hidden='true'></span>".html_safe"
end

To display the result, invoke in your view as

<%= bool_to_glyph(table_boolean_value) %>

Note: For a simple string display, like "yes" and "no" you do not need to invoke html_safe.

value ? "yes" : "no"

Edited: Helper methods

Helper methods are included under app/helpers/[modelnameplural]_helper.rb

module ExamplesHelper

def bool_to_glyph(value)
value ? "<span class='glyphicon glyphicon-ok' aria-hidden='true'></span>".html_safe : "<span class='glyphicon glyphicon-remove' aria-hidden='true'></span>".html_safe"
end

end

If you want the helper to be available to all controllers, add the method to the application_helper.rb.

Correct way to check against boolean values in Rails

Different databases store booleans in different ways. Mysql stores them as 0 or 1. These are translated into false and true by rails. Generally you you treat them as booleans in your ruby code.

This code

if is_admin == true

is redundant. you might as well just say

if is_admin

since the result will be the same either way.



Related Topics



Leave a reply



Submit