Why does false invalidate validates_presence_of?
Ok steps to reproduce this:
prompt> rails test_app
prompt> cd test_app
prompt> script/generate model event_service published:boolean
then go into the migration and add not null and default published to false:
class CreateEventServices < ActiveRecord::Migration
def self.up
create_table :event_services do |t|
t.boolean :published, :null => false, :default => false
t.timestamps
end
end
def self.down
drop_table :ev开发者_开发百科ent_services
end
end
now migrate your changes and run your tests:
prompt>rake db:migrate
prompt>rake
You should get no errors at this time. Now edit the model so that you validate_presence_of published:
class EventService < ActiveRecord::Base
validates_presence_of :published
end
Now edit the unit test event_service_test.rb
:
require 'test_helper'
class EventServiceTest < ActiveSupport::TestCase
test "the truth" do
e = EventService.new
e.published = false
assert e.valid?
end
end
and run rake:
prompt>rake
You will get an error in the test. Now set e.published to true and rerun the test. IT WORKS! I think this probably has something to do with the field being boolean but I can't figure it out. Is this a bug in rails? or am I doing something wrong?
See the API docs...
If you want to validate the presence of a boolean field (where the real values are true and false), you will want to use validates_inclusion_of :field_name, :in => [true, false].
validates_inclusion_of :your_field, :in => [true, false]
no longer works for some versions after 1.3.0 of the shoulda matchers when you are testing that only Boolean values are accepted by your model.
Instead, you should do something like this:
it { should allow_value(true).for(:your_field) }
it { should allow_value(false).for(:your_field) }
it { should_not allow_value(nil).for(:your_field) }
You can see the discussion here.
There was a partial fix for this that now warns if you are trying to do this here
精彩评论