validate_uniqueness_of передает значение nil или пробел (без allow_nil и allow_blank)

StackOverflow https://stackoverflow.com/questions/1480227

Вопрос

Средство проверки уникальности ActiveRecord имеет возможность пропустить проверку, если значение равно нулю или пусто.Даже если я установлю для обоих параметров значение true (поведение по умолчанию) Я могу создать одну запись с нулевым значением и пробелом до начала проверки.Я использую базу данных 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

Содержимое приложения / модели/thing.rb:

class Thing < ActiveRecord::Base
  validates_uniqueness_of :identification
end

Рельсовая консоль:

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).

Установив для обоих из них значение true, я вижу следующее поведение с 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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top