validates_uniqueness_of pasa en nulo o en blanco (sin allow_nil y allow_blank)
-
18-09-2019 - |
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
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