[英]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_save
或after_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.