2010-01-07 6 views
4

У меня есть объект модели (скажем, Parent) с ассоциацией has_many на другом объекте модели (Child).Как обработать новые дети в обратном вызове before_update для вложенных атрибутов activerecord

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

class Child < ActiveRecord::Base 
    belongs_to :parent 
end 

На Родитель, я хочу, чтобы добавить код на before_update обратного вызова, чтобы установить вычисленный атрибут, основанный на своих детей.

Проблема, с которой я столкнулся, заключается в том, что когда я использую метод Parent.update (id, atts), добавляя atts для новых детей, те, которые добавлены в коллекции atts, недоступны во время before_update (self.children возвращает старая коллекция).

Есть ли способ получить новый, не входя в accepts_nested_attributes_for?

ответ

3

То, что вы описываете, работает для меня с Rails 2.3.2. Я думаю, что вы не можете правильно назначать детей родителям. Обновлены ли дети после обновления?

accepts_nested_attributes_for, используемый в вашем вопросе, создает родительский файл child_attributes. У меня такое ощущение, что вы пытаетесь обновить: дети, а не: children_attributes.

Это работает, используя свои модели, как описано, и это следующее before_update обратного вызова:

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

этих команд в консоли:

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

производит этот вывод:

Jimmy 
Julie 
+1

Yep, просто протестировал его, и ваша версия работает. Проблема в том, что я полагался на число детей, которое возвращает старый счет. children.count и children.all.size возвращают 0, в то время как итерация, использующая каждый, на самом деле печатает элементы. Любая идея получения фактического счета? –

+1

Ну, итерации соединения, прежде чем запрашивать размер работал, я пойду с этим подходом. –

+2

Это довольно странно. children.size работает, но не children.all.size или children.count. Остерегайтесь полагаться на счет. Если вы удаляете элементы, счетчик будет выключен, так как он все равно будет считать те, которые помечены для удаления. Вам нужно будет сделать что-то вроде children.reject (&: marked_for_deletion) .count – EmFi