When creating a user, I’m checking if the terms of usage were accepted like so:
# user.rb
class User < ActiveRecord::Base
validates_acceptance_of :terms, :message => :terms_not_accepted, :on => :create
attr_accessible :terms, :on => :create # required because I completely disable mass-assignment in an initializer
end
I have the following fields in my form view:
<label class="checkbox"><%= f.check_box :terms %><span><%=t "users.form.label.terms" %></span></label>
So far, everything works as expected. If the user does not accept the terms, there will be an error message. However, if I just remove the checkbox (and corresponding hidden field generated by the view helper) from the HTML page using e.g. Chrome developer tools, the user will be created!
I can reproduce this in the console:
irb(main):001:0> u = User.new # => #<User ...>
irb(main):002:0> u.terms # => nil
irb(main):003:0> u.save! # => other validations fail, but terms check succeeds!
irb(main):004:0> u.terms = false # => false
irb(main):005:0> u.save! # => terms validation fails as expected
One more info: validates :terms, :acceptance => true yields the same result
I know that I can initialize the terms attribute with false in an after_initialize callback, but I do not want to do that since the validator should be able to handle the nil case. So is this a bug in rails or am I doing something wrong?
If you’d like to make sure that the user accepts terms, then you can set allow_nil to false
http://ar.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#M000082
So change to