簡體   English   中英

如果觸發關聯回調,如何防止觸發模型回調?

[英]How do I prevent a model callback from being triggered if an association callback is triggered?

我有一個模型PositionGroup ,它has_many :positions

每當添加或保存職位時,我希望它更新PositionGroup上的屬性。 例如,當一個新頭寸被添加到PositionGroup ,我想將position.volume添加到現有的position_group.total_units

因此,請考慮以下示例:

pg.total_units = 100 
position2.volume = 50 
# then pg.total_units should be updated to:
pg.total_units = 150

我意識到我可以通過關聯回調來做到這一點,這很好。

問題是,當我想更新先前頭寸的交易量時會發生什么。 如果我添加before_saveafter_save ,那么在觸發after_add回調之后也會觸發該回調——從而人為地誇大pg.total_units數字。

我該如何解決這個問題?

我想出了一個解決方案。

基本上,我沒有使用許多after_save, before_save & after_add回調,我只是在一個模型上使用touch: true在另一個模型上使用after_touch 那解決了我所有的問題。

為了更清楚,在我的Position模型中,我添加了:

belongs_to :position_group, touch: true

然后在我的PositionGroup模型上,我添加了:

after_touch :recompute_total_units

  private

  def recompute_total_units
    update_column(:total_units, positions.sum(:volume))
  end

瞧。

如果我正確理解了這個問題,這里有一種防止人為通貨膨脹的幼稚方法:

class Position < ApplicationRecord
  belongs_to :position_group
  before_save :update_position_group_total_units

  def update_position_group_total_units
    delta = volume - (volume_was || 0)
    position_group.update!(total_units:  position_group.total_units + delta)
  end
end
class PositionGroup < ApplicationRecord
  has_many :positions
end

請參閱此處的文檔: https : //api.rubyonrails.org/classes/ActiveModel/Dirty.html

需要注意的是,如果由於某種原因保存失敗,則 position_group 仍會更新,從而導致不同類型的錯誤計算。

我最喜歡觸摸方法,正如你發現的:

class Position < ApplicationRecord
  belongs_to :position_group, touch: true
end
class PositionGroup < ApplicationRecord
  has_many :positions

  after_touch :recompute_total_units

  private

  def recompute_total_units
    update_column(:total_units, positions.sum(:volume))
  end
end

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM