2010-01-07 3 views
4

I ont un modèle d'objet (disons Parent) avec une association has_many sur un autre modèle d'objet (enfant).Comment traiter les nouveaux enfants en rappel before_update pour activerecord attributs imbriqués

class Parent < ActiveRecord::Base 
    has_many :children 
    accepts_nested_attributes_for :children 
end 

class Child < ActiveRecord::Base 
    belongs_to :parent 
end 

Sur Parent, je veux ajouter du code sur le rappel de before_update pour définir un attribut calculé en fonction de ses enfants.

Le problème que j'ai couru en est que lorsque j'utilise la méthode Parent.update (id, atts), en ajoutant de nouveaux atts pour les enfants, ceux qui sont ajoutés dans la collection atts ne sont pas disponibles pendant before_update (retourne self.children la vieille collection).

Est-il possible de récupérer le nouveau sans déconner avec le accepts_nested_attributes_for?

Répondre

3

Ce que vous décrivez fonctionne pour moi avec Rails 2.3.2. Je pense que vous ne pouvez pas assigner correctement aux enfants d'un parent. Les enfants sont-ils mis à jour après la mise à jour?

accepts_nested_attributes_for, tel qu'il est utilisé dans votre question, crée un écrivain child_attributes sur le parent. J'ai le sentiment que vous essayez de mettre à jour: les enfants par opposition à: children_attributes.

Cela fonctionne en utilisant vos modèles comme décrit et ce rappel before_update suivant:

before_update :list_childrens_names 
def list_childrens_names 
    children.each{|child| puts child.name} 
end 

ces commandes dans la console:

Parent.create # => Parent(id => 1) 
Parent.update(1, :childrens_attributes => 
    [{:name => "Jimmy"}, {:name => "Julie"}]) 

produisent cette sortie:

Jimmy 
Julie 
+1

Ouais, juste testé, et votre version fonctionne. Le problème est que je comptais sur le nombre d'enfants, ce qui renvoie l'ancien compte. children.count et children.all.size retournent tous les deux 0, tandis que l'itération utilisant chaque élément imprime les éléments. Une idée sur l'obtention du compte réel? –

+1

Eh bien, en itérant la connexion avant de demander la taille travaillée, je vais aller avec cette approche. –

+2

C'est assez bizarre. child.size fonctionne, mais pas children.all.size ou children.count. Méfiez-vous de compter sur le nombre. Si vous supprimez des éléments, le nombre sera désactivé, car il comptera toujours ceux qui sont marqués pour la suppression. Vous aurez besoin de faire quelque chose comme children.reject (&: marked_for_deletion) .count – EmFi

Questions connexes