formtastic_tristate_radio

Скачен 5 374 раза

Что оно делает

  1. Provides a custom Formtastic input type :tristate_radio which renders 3 radios (“Yes”, “No”, “Unset”) instead of a checkbox (only where you put it).
  2. Teaches Rails recognize "null" and "nil" param values as nil. See “How it works” ☟ section for technical details on this.
  3. Encourages you to add translations for ActiveAdmin “status tag” so that nil be correctly translated as “Unset” instead of “False”.

Как оно это делает

In Ruby any String is cast to true:

!!""      #=> true
!!"false" #=> true
!!"nil"   #=> true
!!"no"    #=> true
!!"null"  #=> true

Web form params are passed as plain text and are interpreted as String by Rack.

So how Boolean values are transfered as strings if a "no" or "0" and even "" is truthy in Ruby?

Frameworks just have a list of string values to be recognized and mapped to Boolean values:

ActiveModel::Type::Boolean::FALSE_VALUES
#=> [
   0, "0", :"0",
  "f", :f, "F", :F,
  false, "false", :false, "FALSE", :FALSE,
  "off", :off, "OFF", :OFF,
]

so that

ActiveModel::Type::Boolean.new.cast("0")    #=> false
ActiveModel::Type::Boolean.new.cast("f")    #=> false
ActiveModel::Type::Boolean.new.cast(:FALSE) #=> false
ActiveModel::Type::Boolean.new.cast("off")  #=> false
# etc

So what I do in this gem is extend ActiveModel::Type::Boolean in a consistent way to teach it recognize null-ish values as nil:

module ActiveModel
  module Type
    class Boolean < Value

      NULL_VALUES = [nil, "", "null", :null, "nil", :nil].to_set.freeze

      private def cast_value(value)
        NULL_VALUES.include?(value) ? nil : !FALSE_VALUES.include?(value)
      end

    end
  end
end

And voila!

ActiveModel::Type::Boolean.new.cast("")     #=> nil
ActiveModel::Type::Boolean.new.cast("null") #=> nil
ActiveModel::Type::Boolean.new.cast(:null)  #=> nil
ActiveModel::Type::Boolean.new.cast("nil")  #=> nil
ActiveModel::Type::Boolean.new.cast(:nil)   #=> nil

Warning: as you might have noticed, default Rails behavior is changed. If you rely on Rails’ automatic conversion of strings with value "null" into true, this gem might not be for you (and you are definitely doing something weird).

Ссылки