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

2019-01-11 06:07发布

问题:

I know I could easily write a function and put it in the application controller, but I'd rather not if there is something else that does this already. Basically I want to have something like:

>> boolean_variable?
=> true
>> boolean_variable?.yesno
=> yes
>> boolean_variable?.yesno.capitalize
=> Yes

is there something like this already in the Rails framework?

回答1:

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


回答2:

There isn't something in Rails.

A better way than adding to the true/false classes to achieve something similar would be to make a method in ApplicationHelper:

def human_boolean(boolean)
    boolean ? 'Yes' : 'No'
end

Then, in your view

<%= human_boolean(boolean_youre_checking) %>

Adding methods to built-in classes is generally frowned upon. Plus, this approach fits in closely to Rails' helpers like raw().

Also, one offs aren't a great idea as they aren't easily maintained (or tested).



回答3:

There is a gem for that now: humanize_boolean

Then you just do:

true.humanize # => "Yes" 
false.humanize # => "No"

It also supports internationalization so you can easily change the returned string by including your translation for en.boolean.yes and en.boolean.no (or any locale you like)



回答4:

Alternatively, you could also do one offs in your views such as:

<%= item.bool_field? ? 'yes' : 'no' %>


回答5:

The humanize_boolean gem extends the TrueClass, FalseClass and NilClass which is an indirect extension I would prefer to avoid.

I've found this helper with a top level translation is isolated, friendly to change and you can give it anything truthy or falsey:

# app/helpers/application_helper.rb
class ApplicationHelper
  def humanize_boolean(boolean)
    I18n.t((!!boolean).to_s)
  end
end

# config/locales/en.yml
en:
  :true: 'Yes'
  :false: 'No'

Doing !!(boolean).to_s ensures the variables passed to the argument is either a "true" or "false" value when building the translation string.

In use:

# app/views/chalets/show.html.erb
<%= humanize_boolean(chalet.rentable?) %>