71 votes

accepts_nested_attributes_for child association validation failing

J'utilise accepts_nested_attributes_for dans un de mes modèles Rails, et je veux sauvegarder les enfants après avoir créé le parent.

Le formulaire fonctionne parfaitement, mais la validation échoue. Pour simplifier, imaginez ce qui suit :

class Project < ActiveRecord::Base
  has_many :tasks
  accepts_nested_attributes_for :tasks
end

class Task < ActiveRecord::Base
  belongs_to :project

  validates_presence_of :project_id
  validates_associated :project
end

Et je cours :

Project.create!(
  :name => 'Something',
  :task_attributes => [ { :name => '123' }, { :name => '456' } ]
)

Lors de l'enregistrement du modèle de projet, la validation échoue sur les tâches car elles n'ont pas de project_id (puisque le projet n'a pas été enregistré).

Il semble que Rails suive le modèle ci-dessous :

  • Valider le projet
  • Valider les tâches
  • Sauver le projet
  • Sauvegarder les tâches

Le modèle devrait être :

  • Valider le projet
  • Sur Pass : Sauvegarder le projet et continuer...
  • Valider les tâches
    • On Pass : Sauvegarder les tâches
    • En cas d'échec : Supprimer le projet (retour en arrière peut-être ?)

Donc ma question se résume à : Comment puis-je faire en sorte que Rails exécute la méthode project_id= (ou project=) et la validation sur les enfants (tâches) APRÈS que le parent (projet) ait été sauvegardé, mais ne sauvegarde PAS le modèle parent (projet) si un enfant (tâche) est invalide ?

Des idées ?

0voto

Thomas Watson Points 2260

Contrairement à ce que suggère bigo, il n'est pas toujours acceptable de sauvegarder d'abord l'objet parent et ensuite les enfants. En général, vous voulez vous assurer que tous les objets sont validés avant de commencer à les enregistrer. Cela donne à l'utilisateur la possibilité de rééditer le formulaire de saisie et de corriger les erreurs éventuelles.

Le problème que vous décrivez sera corrigé dans Rails 3.0. J'aurais bien posté un lien vers le ticket Lighthouse, mais stackoverflow.com ne le permet pas car je suis un nouvel utilisateur (#fail). Mais pour l'instant, vous pouvez utiliser le plugin " contrôle parental ", ce qui corrigera votre "bug".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X