validates_uniqueness_of 传递 nil 或空白(没有allow_nil 和allow_blank)
ActiveRecord 的唯一性验证器有一个选项可以跳过验证,如果值为 nil 或空白。即使我将两个参数设置为 true(默认行为),我也可以在验证命中之前创建一条包含 nil 和空白的记录。我使用默认的 SQlite3 数据库 sqlite3-ruby (1.2.5)。
编辑以澄清:如果将 validates_presence_of
添加到模型,我会得到预期的结果。我认为 validates_uniqueness_of 的默认行为会让这个变得多余。
测试用例:
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
为什么前两个创建会通过?
谢谢
The uniqueness validator of ActiveRecord has an options to skip validation if the value is nil or blank. Even if I set both parameters to true (the default behaviour) I can create one record with nil and blank before the validation hits. I use the default SQlite3 Database sqlite3-ruby (1.2.5).
Edit for clarification: I get the expected result if I add validates_presence_of
to the Model. I thought that the default behaviour of validates_uniqueness_of
would make this redundant.
Testcase:
rails validation_test
cd validation_test/
script/generate Model Thing identification:string
rake db:migrate
Content of app/models/thing.rb:
class Thing < ActiveRecord::Base
validates_uniqueness_of :identification
end
Rails console:
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
Why do the first two creations pass?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您对默认行为有误解。来自文档:
将
allow_blank
设置为 true,我在 Rails 2.3.4 中看到以下行为。编辑:进行澄清。
添加
validates_presence_of
对于您想要执行的操作来说是正确的。它不是多余的,因为它正在检查完全不同的错误情况。它还有自己的错误消息,这对用户来说很重要。You are mistaken about the default behavior. From the docs:
Setting
allow_blank
to true, I see the following behavior with Rails 2.3.4.Edit: Addressing your clarification.
Adding a
validates_presence_of
would be correct for what you're trying to do. It's not redundant, since it's checking for a completely different error case. It also has its own error message, which will be important for the user.并使用
验证
:and with
validates
: