2009-12-27 17 views
1

Je trouve (noodling autour dans le script/console) que si j'ajoute un nouvel élément à la collection associée, je n'ai pas appeler foo.reload pour voir le changement qui en résulte:Devrait-il être nécessaire d'appeler ActiveRecord :: Base.reload après la mise à jour d'une collection d'attributs imbriqués?

foo.bars 
=> [] 
foo.bars_attributes = [{ :person_id => '288', :task_id => '1237' }] 
=> [{ :person_id=>"288", :task_id=>"1237" }] 
foo.save 
=> true 
foo.bars 
=> [#<Bar id: 6, person_id: 288, task_id => 1237>] 

Terrific. Mais quand je supprimer un élément de la collection, je dois appeler foo.reload avant le changement (visible dans DB après un appel à sauvegarder) se reflète dans ma collection:

foo.bars_attributes = [{ :id => '6', :_delete => '1' }] 
= [{ :_delete=>"1", :id=>"6" }] 
foo.save 
=> true 
foo.bars 
=> [#<Bar id: 6, person_id: 288, task_id => 1237>] 
foo.reload 
foo.bars 
=> [] 

Est-ce normal, ou suis-je faire quelque chose de mal dans la mise à jour de l'association?

Répondre

0

Je vois la même chose dans les rails 3.0 (pas encore publié au moment de votre écriture). Il faisait des ravages avec une validation qui nécessitait un nombre minimum d'associations. L'instance parent dirait qu'elle était valide, même après que la mise à jour ait supprimé tous les attributs enfants.

Je mis au point une solution de contournement en incluant un module dans mon modèle Parent avec la méthode suivante, et son remplacement par ce que pour update_attributes() méthode update du contrôleur:

def update_with_association_size_validations(attributes) 
    update_successful = false 
    self.class.transaction do 
     self.update_attributes(attributes) 
     self.reload 
     update_successful = true if self.valid? 
     raise ActiveRecord::Rollback unless update_successful 
    end 
    update_successful 
    end 

C'est pas une solution parfaite, et il est non testé sur des associations plus profondément imbriquées.

Mieux vaut que jamais, presque un an jour pour jour!