I've got the following Model:
class GuestCatering < ActiveRecord::Base
# Valida开发者_开发技巧tion
validates :name, :presence => true
validates :order_number, :presence => true
validates :orderable, :presence => true
end
But when I'll try to update an existing GuestCatering with the following code:
guest_catering.update_attributes(:orderable => false)
The guest catering variable is a valid GuestCatering object. The guest_catering object has errors after the update, like that:
<{[:orderable, ["can't be blank"]]=>nil}>
But when i pass a orderable => true
, everything is fine and no errors.
What's wrong here, why can't i set orderable to false?
Your model is actually behaving exactly as you told it to, through your use of validates :orderable, :presence => true
There's little point validating the presence of a boolean flag - it's going to be true
, nil
or false
- and in Ruby world, nil and false have the same semantic value when it comes to boolean logic.
Internally, validates :presence
relies on the value of the attribute being checked to return false
when blank?
is called. And, in Rails (with ActiveSupport), false.blank?
evaluates as true
- which means that your field is failing the validation.
Simply remove that validation and everything will work as expected.
Like Dan Cheail already said in his answer, a nil
and false
boolean is semantically the same thing.
But, if you really need to validate it (not allowing nil
), you can always do :
validates_inclusion_of :orderable, :in => [true, false]
Instead of validates :presence => :true
, you should write your migrations with the default value like this:
t.boolean :orderable, :default => 0
I assume your default value should be false
. If true
, use 1 as default. Then it will set the default value in database. So, you can omit the validation check.
The reason you cannot use validates :presence
is answered by @dan. Presence means not blank and Rails use .blank?
function for this and false.blank?
is true
精彩评论