Pregunta

El validador singularidad de ActiveRecord tiene una opciones para saltar la validación si el valor es nulo o en blanco. Incluso si ambos parámetros a true (el comportamiento por defecto) que puede crear un registro con nulas y en blanco antes de los éxitos de validación. Utilizo el defecto Sqlite3 base de datos sqlite3-ruby (1.2.5).

Editar una aclaración: Me sale el resultado esperado si añado validates_presence_of al modelo. Yo creía que el comportamiento predeterminado de validates_uniqueness_of lo haría redundante.

caso_prueba:

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

Contenido de aplicación / modelos / thing.rb:

class Thing < ActiveRecord::Base
  validates_uniqueness_of :identification
end

Barras de consola:

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

¿Por qué pasan las dos primeras creaciones?

Gracias

¿Fue útil?

Solución

Se equivoca sobre el comportamiento predeterminado. De los documentos :

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

Configuración de ambas cosas a la verdad, veo el comportamiento siguiente con rieles 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">

Editar:. Dirigiéndose a su aclaración La adición de un validates_presence_of sería correcto para lo que estamos tratando de hacer. No es redundante, ya que es la comprobación de un caso de error completamente diferente. También tiene su propio mensaje de error, que será importante para el usuario.

class Thing < ActiveRecord::Base
  validates_uniqueness_of :identification, :allow_nil => true, :allow_blank => true
  validates_presence_of :identification
end
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top