6

I'm a newb at programming but in my application I want certain cases to display "yes" or "no" instead of "true" or "false". I'm not sure the best way to do this, I read this question but didn't really understand how to implement it. Can someone help me, would it be best to put this in the initializers, helpers, or somewhere else? I want to be able to call something in my views wherever I want the Yes/No to be displayed, or alternatively to create a custom data type where in my migation I can just create something like t.boolean_yesno and then for each column I do that to it will just store trues as yes and falses as no.

I'd appreciate a hand in getting me on the right track, I have no experience with initializers or helpers. Thanks!

2
  • Look into how to create a helper. That's the right direction. Commented Feb 24, 2013 at 1:45
  • possible duplicate of Rails (or Ruby): Yes/No instead of True/False Commented Nov 22, 2013 at 18:18

3 Answers 3

27

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.

Sign up to request clarification or add additional context in comments.

6 Comments

Besides accepting your answer I wanted to give you a huge THANKS for taking the time and describing these options so well!
I'm not able to get the locale working properly... Right now when I did <td><%= e.autolyse.class %></td> The output in my table is showing "TrueClass", not "Yes". What did I do wrong? The helper method solution worked great though
You're seeing TrueClass, and that's a great start. You need to wrap it in the #t a.k.a. #translate method like this: <%= t e.autolyse.class %> The #t method is what calls the locales lookup.
I tried that but its just showing me "true" and "false" when I use <%= t e.autolyse.class %>... ugh not sure what could be wrong... I tried also <%= t 'e.autolyse.class' %> and that shows me now "Class" for everything. I want to figure this out though it looks like the best way
got it! can you edit your answer to reflect? Basically the mistake was in the YAML file you have to have quotes around the "Yes" and "No", otherwise it was still showing me true and false
|
3

The simplest option to get setup is to create a helper method which you can put in the application helper.

# in app/helpers/application_helper.rb

def boolean_to_words(value)
  value ? "Yes" : "No"
end

This is analogous to many other Rails conversion helpers such as number_to_currency

Comments

0

Assuming you have :boolean attribute in your model/database, you can do this:

class Foo < ActiveRecord::Base
  def bar
    self[:bar] ? 'Yes' : 'No'
  end
end

The whenever you want the "Yes"/"No" value, call @foo.bar. Whenever you want the true/false value, call @foo.bar? or @foo[:bar].

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.