recursos rails formularios form for anidados ruby-on-rails activerecord callback nested-attributes

ruby-on-rails - formularios - nested form rails



Los atributos anidados de Rails no se activan devoluciones de llamada (2)

Tengo un problema extraño en el que los devoluciones de llamada de los niños no se activan cuando se actualiza el padre ...

Tengo la siguiente configuración de modelo:

class Budget < ActiveRecord::Base has_many :line_items accepts_nested_attributes_for :line_items end

class LineItem < ActiveRecord::Base belongs_to :budget before_save :update_totals private def update_totals self.some_field = value end end

En mi formulario, tengo los campos anidados (creados usando fields_for ):

= form_for @budget do |f| = f.text_field :name = f.fields_for :line_items do |ff| = ff.text_field :amount

¿Por qué la devolución de llamada update_totals en el niño nunca se despide / qué puedo hacer para que se dispare?


Tuve el mismo problema. before_save callback no se llama cuando el modelo no se cambia.

Está actualizando line_items , no el budget , por lo que Rails cree que no está actualizado y no line_items save para ello.

before_save cambiar before_save por after_validation para que se llame, incluso si el modelo no tiene atributos modificados. Y cuando en esta devolución de llamada usted cambia algunos atributos, los rieles verán que su modelo ha cambiado y llamará save .


Vieja pregunta, lo sé, pero todavía aparece primero en la búsqueda. Creo que este artículo tiene una solución:

Rieles, atributos anidados y devoluciones de llamada before_save

Si entiendo ese artículo correctamente, el problema (como explica @AntonDieterle en su respuesta) es que la devolución de llamada secundaria no se activa porque el padre no está "sucio". La solución de este artículo es "forzarlo" para que se ensucie llamando a attr_name_will_change! en un atributo padre que, de hecho, no cambia. Ver [Active Model Dirty] en la API de Rails 2 .

La solución de Anton de usar after_validation lugar de before_save suena más simple, pero quería poner esto por ahí como alternativa.