validates_uniqueness_of passa nullo o vuoto (senza allow_nil e allow_blank)
-
18-09-2019 - |
Domanda
Il validatore unicità di ActiveRecord ha una possibilità di saltare convalida se il valore è nullo o vuoto. Anche se ho impostato entrambi i parametri su true (il comportamento predefinito) posso creare un record con nulla e vuota prima i colpi di convalida. Io uso il database sqlite3 sqlite3-ruby predefinito (1.2.5).
Modifica di chiarimenti: ottengo il risultato previsto se aggiungo validates_presence_of
al Modello. Ho pensato che il comportamento predefinito di validates_uniqueness_of
renderebbe questo ridondante.
Testcase:
rails validation_test
cd validation_test/
script/generate Model Thing identification:string
rake db:migrate
Contenuto di app / modelli / 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
Perché passano le prime due creazioni?
Grazie
Soluzione
Vi sbagliate circa il comportamento di default. Da la documentazione :
: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).
Impostazione sia di quelli al vero, vedo il seguente comportamento con 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">
Modifica:. Affrontare il tuo chiarimento
L'aggiunta di un validates_presence_of
sarebbe corretto per quello che stai cercando di fare. Non è superfluo, dal momento che è il controllo per una completamente diversa caso di errore. Essa ha anche un proprio messaggio di errore, che sarà importante per l'utente.
class Thing < ActiveRecord::Base
validates_uniqueness_of :identification, :allow_nil => true, :allow_blank => true
validates_presence_of :identification
end