How are values cast when assigning to a Boolean field in Rails ActiveRecord? -
short version of question
in rails activerecord, if have boolean field , assign "abc" or 2, gets cast false. value 1 cast true, , nil remains nil. why case? can find rails documentation (or ruby documentation) explains behavior?
long version of question
i having difficulty understanding how rails handles attempts assign values boolean field in rails model. example, let's have website model has string field called :domain , boolean field called :can_ssl.
my migration looks this:
class createwebsites < activerecord::migration def change create_table :websites |t| t.string :domain t.boolean :can_ssl, :default => false t.timestamps end end end in model file, add validation rules, looks this:
class website < activerecord::base validates :domain, :presence => true validates :can_ssl, :inclusion => { :in => [true, false] } end simple enough. based on i've done, i'm expecting :can_ssl can set values true or false, , nothing else. else result in valid? being false.
but once start playing around in console, notice that, actual assignment statement, value provide being recast true or false (or nil). rules governing how value gets cast boolean?
examples console:
w = website.new w.domain = 'stackoverflow.com' w.can_ssl = true w.can_ssl # => true w.valid? # => true w.can_ssl = nil w.can_ssl # => nil w.valid? # => false (so far good) w.can_ssl = 'abc' w.can_ssl # => false (how did 'abc' become value false?) w.valid? # => true w.can_ssl = 1 w.can_ssl # => true (i guess makes sense 1 casts true) w.valid? # => true w.can_ssl = 2 w.can_ssl # => false (but other 1 casts false?) w.valid? # => true so, based on i've done far, think can conclude following:
- when assigning value
1ortruebooleanfield, value casttrue, assigned. - when assigning
nilbooleanfield, field assignednil. - when assigning else (such
stringor number not1), value castfalse.
am understanding correctly? missing anything?
i'm having difficulty finding documentation boolean field type in rails can give me clarification on this.
this done in bowels of activerecord: with
activerecord::connectionadapters::column.value_to_boolean at least in version of rails (it may somewhere different in more recent versions).
here's source in version
# file activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 144 144: def value_to_boolean(value) 145: if value.is_a?(string) && value.blank? 146: nil 147: else 148: true_values.include?(value) 149: end 150: end where true_values defined
#activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb:10: true_values = [true, 1, '1', 't', 't', 'true', 'true'].to_set 1, 0, "f" , "t" there because of popular dbms's mysql & postgresql, store bools 0/1 , "f"/"t" respectively.
it's worth noting difference between , passes "if" test in ruby/rails, ie values "truthy" or "falsy" ("falsy" values fail if test, "truthy" values pass it).
in ruby, nil , false "falsy" , literally anything else (including 0, empty arrays, empty strings, empty hashes etc) "truthy". so, there's massive disparity between deemed truthy/falsy in ruby , saved true/false boolean database column.
Comments
Post a Comment