emr*_*ass 1 validation ruby-on-rails ruby-on-rails-3
在创建用户时,我正在检查是否接受了使用条款,如下所示:
# 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
Run Code Online (Sandbox Code Playgroud)
我在表单视图中有以下字段:
<label class="checkbox"><%= f.check_box :terms %><span><%=t "users.form.label.terms" %></span></label>
Run Code Online (Sandbox Code Playgroud)
到目前为止,一切都按预期工作.如果用户不接受条款,则会出现错误消息.但是,如果我只是使用Chrome开发人员工具从HTML页面中删除复选框(以及由视图帮助程序生成的相应隐藏字段),则将创建用户!
我可以在控制台中重现这个:
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
Run Code Online (Sandbox Code Playgroud)
还有一个信息:validates :terms, :acceptance => true产生相同的结果
我知道我可以false在after_initialize回调中初始化terms属性,但我不想这样做,因为验证器应该能够处理这种nil情况.那么这是rails中的错误还是我做错了什么?
如果您想确保用户接受条款,则可以将allow_nil设置为false
http://ar.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#M000082
:allow_nil - Skip validation if attribute is nil (default is true).
Run Code Online (Sandbox Code Playgroud)
所以改为
validates_acceptance_of :terms, :on => :create, :allow_nil => false, :message => :terms_not_accepted,
Run Code Online (Sandbox Code Playgroud)