| Merci pour vos réponse, le plugin que Fabien propose est pas mal, il faudra que je le teste.
En fait, lorsque je fais des tests via la console Ruby tout marche comme prévu, c'est à dire que si je fais :
>> p2 = Property.new => #<Property id: nil, type: "Property", version_id: nil, name: nil, value: nil, created_at: nil, updated_at: nil>
>> p3 = Property.new => #<Property id: nil, type: "Property", version_id: nil, name: nil, value: nil, created_at: nil, updated_at: nil>
>> v = Version.find :first => #<Version id: 1, num: 1, description: "des v1", created_at: "2009-05-06 16:10:50", updated_at: "2009-05-06 16:10:50">
>> p2.version = v => #<Version id: 1, num: 1, description: "des v1", created_at: "2009-05-06 16:10:50", updated_at: "2009-05-06 16:10:50">
>> p3.version = v => #<Version id: 1, num: 1, description: "des v1", created_at: "2009-05-06 16:10:50", updated_at: "2009-05-06 16:10:50">
>> p3.name = "req22" => "req22"
>> p2.name = "req22" => "req22"
>> p2.value = "r22" => "r22"
>> p3.value = "r33" => "r33"
>> p3.save and p2.save => false
v.properties => [#<Property id: 21, type: "Property", version_id: 1, name: "req22", value: "r33", created_at: "2009-05-07 20:36:53", updated_at: "2009-05-07 20:36:53">]
Ici, on voit très bien que p2 n'est pas ajouté à la base de données.
Le problème avec mon application, c'est que la saisie se fait via un formulaire généré à la volé (du _javascript_)
Je passe par de tas de partiels pour afficher ce formulaire...
Je me suis dis que ce peut être ActiveRecord insère les deux lignes en une seule requête, mais lorsque j'ai consulté les logs j'ai trouvé que ce n'est pas le cas. C'est atomique, voici un bout de log :
SQL (0.4ms) INSERT INTO "properties" ("name", "updated_at", "version_id", "value", "created_at") VALUES(E'req2', '2009-05-06 18:23:49.090473', 3, E'hgjhg', '2009-05-06 18:23:49.090473') RETURNING "id"
SQL (0.4ms) INSERT INTO "properties" ("name", "updated_at", "version_id", "value", "created_at") VALUES(E'req2', '2009-05-06 18:23:49.096753', 3, E'lkj', '2009-05-06 18:23:49.096753') RETURNING "id"
SQL (0.4ms) INSERT INTO "properties" ("name", "updated_at", "version_id", "value", "created_at") VALUES(E'req2', '2009-05-06 18:23:49.098239', 3, E'kjlkj', '2009-05-06 18:23:49.098239') RETURNING "id"
SQL (0.4ms) INSERT INTO "properties" ("name", "updated_at", "version_id", "value", "created_at") VALUES(E'req2', '2009-05-06 18:23:49.099697', 3, E'sdfasdf', '2009-05-06 18:23:49.099697') RETURNING "id"
cela ne vient pas du fait que j'utilise du _javascript_ ?
On 7 mai 09, at 03:08, Fabien Jakimowicz wrote: 2009/5/7 Cyril Mougel <[email protected]> ALAHYANE Rachid a écrit : > Bonjour, > > Je suis entrain de développer une application dans laquelle j'ai > besoin, à un moment donné, d'insérer plusieurs entrées dans une table: > > -------------------------------------------------- > property.rb > -------------------------------------------------- > class Property < ActiveRecord::Base > belongs_to :version > validates_presence_of :name, :value > validates_uniqueness_of :name, :scope => :version_id > end > -------------------------------------------------- > la table associée à ce model contient les colonnes : id, name, value > et version_id > > -------------------------------------------------- > version.rb > -------------------------------------------------- > class Version < ActiveRecord::Base > has_many :properties ,:dependent => :destroy #e.g ON CASCADE > delete > accepts_nested_attributes_for :properties,:allow_destroy => true > end > -------------------------------------------------- > la table associée contient les colonnes : id et numero > > Le problème que j'ai est le suivant : lorsque j'insère via un > formulaire associé à la version 1 par exemple > > prop1 de valeur p1 > et > prop1 de valeur p2 > > les deux entrées sont insérées dans la table properties, ici, je viole > la contrainte validates_uniqueness_of, mais je ne reçois aucune > erreur, et les entrées sont insérées :( Est-ce validates_uniqueness_of > qui ne fonctionne pas bien ? ou bien j'ai autres chose à rajouter ? > > Si ma question n'est pas claire je peux la détailler encore. > Tu peux le détailler avec un test unitaire? Ca sera largement plus simple a lire.
C'est un débat courant avec ruby on rails : la validation d'uniqueness ne devrait pas être situé au niveau modèle, mais au niveau base de données sous forme de contrainte. C'est la seule façon de valider correctement ton unicité.
Tu devrais déclarer un index unique sur la colone (ou son ensemble) que tu souhaites puis catcher l'exception levée en cas de violation de la contrainte (ActiveRecord::StatementInvalid). Enfin, vérifier qu'il s'agit bien de la contrainte d'unicité qui est relevée puis traiter le cas et raiser ActiveRecord::Rollback pour remettre la transaction sql dans un état correct.
Il existe un plugin permettant de gérer ces contraintes (et d'autres) pour postgresql, c'est en cours de discussion sur rails-core pour une éventuelle modification du core afin de gérer plus proprement ce genre de cas. Mais on est encore loin d'avoir une chose uniforme pour cela : http://github.com/pedz/activerecord_constraints/tree/master
Je crois que certains parlent même de développer une sorte de gestionnaire de validations qui permettrait à un endroit de déclarer ses règles de validation, d'avoir les contraintes sql liées et de remonter les erreurs de validations ActiveRecord. -- http://fabien.jakimowicz.com --~--~---------~--~----~------------~-------~--~----~ Vous avez reçu ce message, car vous êtes abonné au groupe "Railsfrance" de Google Groups. Pour transmettre des messages à ce groupe, envoyez un e-mail à l'adresse [email protected] Pour résilier votre abonnement envoyez un e-mail à l'adresse [email protected] -~----------~----~----~----~------~----~------~--~---
Meilleures salutations / Best Regards
Rachid ALAHYANE
|