I have the following validation on an attribute of a model:
validates :on_ride_photo,
presence: true,
inclusion: { in: [true, false] }
I then have the following tests:
context 'on_ride_photo' do
it { should validate_presence_of(:on_ride_photo) }
it { should allow_value(true).for(:on_ride_photo) }
it { should allow_value(false).for(:on_ride_photo) }
it { should_not allow_value(nil).for(:on_ride_photo) }
it { should_not allow_value(4).for(:on_ride_photo) }
it { should_not allow_value('yes').for(:on_ride_photo) }
end
But I get the following error when running my specs:
2) Coaster validations should allow on_ride_photo to be set to false
Failure/Error: it { should allow_value(false).for(:on_ride_photo) }
Did not expect errors when on_ride_photo is set to false, got error:
# ./spec/models/coaster_spec.rb:86:in `block (3 levels) in <top (required)>'
Is the fact that I want to allow false as a valid value being knocked down by the fact it has to be present and that false is classed as not present? If so, then how can I work around this?
Yes, the issue is with
presence: true
, which checks that the attribute is notObject#blank?
. Since the validations are additive, theinclusion:
clause can't "override" the fact thatfalse
fails thepresence
test.The following is from http://edgeguides.rubyonrails.org/active_record_validations.html#presence:
See Billy Chan's answer for a discussion of how boolean fields are handled, including in particular information on which values are treated as
nil
,true
andfalse
.