validates_uniqueness_of传递nil或空白(没有allow_nil和allow_blank)

如果值为零或空白,ActiveRecord的唯一性validation程序会跳过validation。 即使我将这两个参数都设置为true(默认行为),我也可以在validation命中之前创build一个零和空白的logging。 我使用默认的SQlite3数据库sqlite3-ruby(1.2.5)。

编辑澄清:如果我将validates_presence_of添加到模型,我会得到预期的结果。 我认为validates_uniqueness_of的默认行为会使这个冗余。

testing用例:

 rails validation_test cd validation_test/ script/generate Model Thing identification:string rake db:migrate 

app / models / thing.rb的内容:

 class Thing < ActiveRecord::Base validates_uniqueness_of :identification end 

Rails控制台:

 script/console Loading development environment (Rails 2.3.4) >> Thing.create! => #<Thing id: 1, identification: nil, created_at: "2009-09-26 01:49:32", updated_at: "2009-09-26 01:49:32"> >> Thing.create! :identification => "" => #<Thing id: 2, identification: "", created_at: "2009-09-26 01:49:42", updated_at: "2009-09-26 01:49:42"> >> Thing.create! :identification => "" ActiveRecord::RecordInvalid: Validation failed: Identification has already been taken from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/validations.rb:1090:in `save_without_dirty!' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/dirty.rb:87:in `save_without_transactions!' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/transactions.rb:200:in `save!' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `transaction' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/transactions.rb:182:in `transaction' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/transactions.rb:200:in `save!' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/transactions.rb:208:in `rollback_active_record_state!' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/transactions.rb:200:in `save!' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/validations.rb:1059:in `create!' from (irb):3 >> Thing.count => 2 

为什么前两个作品会通过?

谢谢

你错误的默认行为。 从文档 :

 :allow_nil - If set to true, skips this validation if the attribute is nil (default is false). :allow_blank - If set to true, skips this validation if the attribute is blank (default is false). 

设置这两个为真,我看到了Rails 2.3.4的以下行为。

 class Thing < ActiveRecord::Base validates_uniqueness_of :identification, :allow_blank => true, :allow_nil => true end >> Thing.create! :identification => "" => #<Thing id: 6, identification: "", created_at: "2009-09-26 03:09:48", updated_at: "2009-09-26 03:09:48"> >> Thing.create! :identification => "" => #<Thing id: 7, identification: "", created_at: "2009-09-26 03:09:49", updated_at: "2009-09-26 03:09:49"> >> Thing.create! :identification => nil => #<Thing id: 8, identification: nil, created_at: "2009-09-26 03:09:52", updated_at: "2009-09-26 03:09:52"> >> Thing.create! :identification => nil => #<Thing id: 9, identification: nil, created_at: "2009-09-26 03:09:53", updated_at: "2009-09-26 03:09:53"> 

编辑:解决您的澄清。 添加一个validates_presence_of对于你要做的事是正确的。 这不是多余的,因为它正在检查一个完全不同的错误情况。 它也有自己的错误信息,这对用户来说很重要。

 class Thing < ActiveRecord::Base validates_uniqueness_of :identification, :allow_nil => true, :allow_blank => true validates_presence_of :identification end