Question

Le caractère unique de validateur ActiveRecord a un choix de sauter validation si la valeur est nulle ou vide. Même si je mets les deux paramètres true (le comportement par défaut) Je peux créer un enregistrement avec nul et vierge avant les coups de validation. J'utilise la valeur par défaut Sqlite3 Base de données sqlite3-ruby (1.2.5).

Modifier des éclaircissements: je reçois le résultat attendu si j'ajoute validates_presence_of au modèle. Je pensais que le comportement par défaut de validates_uniqueness_of rendrait cette redondance.

Testcase:

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

Contenu de l'application / modèles / 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

Pourquoi les deux premières créations passent?

Merci

Était-ce utile?

La solution

Vous vous trompez sur le comportement par défaut. De les docs :

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

Réglage des deux de ceux vrai, je vois le comportement suivant avec 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">

Modifier. Répondre à vos précisions Ajout d'un validates_presence_of serait correct pour ce que vous essayez de faire. Ce n'est pas redondant, car il est la vérification d'un cas d'erreur complètement différent. Il a également son propre message d'erreur, ce qui est important pour l'utilisateur.

class Thing < ActiveRecord::Base
  validates_uniqueness_of :identification, :allow_nil => true, :allow_blank => true
  validates_presence_of :identification
end
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top