Rails嵌套属性不会触发子回调

set*_*rgo 21 activerecord ruby-on-rails callback nested-attributes

我遇到了一个奇怪的问题,当更新父级时,不会触发子回调...

我有以下模型设置:

class Budget < ActiveRecord::Base
  has_many :line_items
  accepts_nested_attributes_for :line_items
end
Run Code Online (Sandbox Code Playgroud)

 

class LineItem < ActiveRecord::Base
  belongs_to :budget

  before_save :update_totals

  private
  def update_totals
    self.some_field = value
  end
end
Run Code Online (Sandbox Code Playgroud)

在我的表单中,我有嵌套的字段(使用构建fields_for):

= form_for @budget do |f|
  = f.text_field :name
  = f.fields_for :line_items do |ff|
    = ff.text_field :amount
Run Code Online (Sandbox Code Playgroud)

为什么update_totals孩子的回调从未被解雇/我该怎么办才能解雇?

Ant*_*rle 35

我遇到过同样的问题.before_save未更改模型时不调用回调.

你正在更新line_items,而不是budget,所以rails认为它没有更新,也没有要求save它.

您需要更改before_saveafter_validation即使模型没有更改属性也会调用它.在此回调中,您更改了一些属性,rails会看到您的模型已更改并将调用save.


Mar*_*rry 9

老问题,我知道,但它仍然首先出现在搜索中.我认为这篇文章有一个解决方案:

Rails,嵌套属性和before_save回调

如果我正确地理解了这篇文章,那么问题(正如@AntonDieterle在他的回答中所解释的那样)是因为父母不是"脏"而没有触发子回调.这个arcticle的解决方案是通过调用attr_name_will_change!实际上不会改变的父属性来"强迫"它变脏.请参阅Rails API 2中的[Active Model Dirty] .

安东的解决方案使用after_validation而不是before_save听起来更简单,但我想把它放在那里另一种选择.

  • 第一个链接不再起作用 (3认同)
  • WayBackMachine来救援!试试http://web.archive.org/web/20150613004201/http://tamersalama.com/2011/11/10/rails-nested-attributes-and-before_save-callbacks (2认同)