由于原来的问题没有切中要害,这里有一个重新编写的版本,更好地描述这个问题。
我有以下型号:
class LineItem < ApplicationRecord
has_many :line_item_options, :dependent => :destroy
has_many :options, through: :line_item_options
end
class LineItemOption < ApplicationRecord
belongs_to :option
belongs_to :line_item
has_many :charges, as: :chargeable, dependent: :destroy
after_create :build_charges
def build_charges
surcharges.each do |surcharge|
self.charges.create!(
surcharge_id: surcharge.id,
name: surcharge.name
)
end
end
end
class Charge < ApplicationRecord
belongs_to :chargeable, polymorphic: true
end
LineItemOption是加入模型,其加入一个选项(未示出)以一个LineItem的。在某些情况下,LineItemOption也将有一个孩子收费模式。
在我的LineItem形式,我有以下代码:
= line_item.collection_check_boxes :option_ids, group.options, :id, :name_and_price do |option|
.checkbox
= option.check_box(class: "check")
= option.label
当使用collection_check_boxes
形式帮手,如预期的after_create
回调火灾创造了LineItemOption。然而,当一个LineItemOption使用此相同的形式帮助销毁没有回调被触发。为了验证这一点,我已经使用has_many :charges, as: :chargeable, dependent: :destroy
以及一个before_destroy回调。在这两种情况下的回调从铁轨控制台工作,但不是collection_check_boxes形成帮手。
纵观服务器日志中我可以看到,销毁方法被调用上愉快地运行,而无需还运行相应的回调LineItemOption
LineItemOption Destroy (0.7ms) DELETE FROM "line_item_options" WHERE "line_item_options"."line_item_id" = $1 AND "line_item_options"."option_id" = $2 [["line_item_id", 12], ["option_id", 1]]
(1.2ms) COMMIT
Redirected to http://localhost:3000/orders/6
林坐在这里抓我的头试图找出怎么回事,以及如何解决它。与collection_check_boxes
帮助这个共同的行为?
它看起来像有,因为很久以前就是当你从after_destroy
协会has_many :through
删除记录的https://github.com/rails/rails/issues/27099回调不会触发在轨道中的错误或东西(我猜dependant: :destroy
选项取决于回调)。
你必须实现某种哈克解决方案一样,分配新line_items之前,这样做line_item.line_item_options.destroy_all
或line_item.line_item_options.each(&:destroy)
手工删除记录触发propper回调,然后更新记录,这样的轨道可能会无车destoy行为创建新的关联。
您必须包括:
has_many :line_item_options, :dependent => :destroy
accepts_nested_attributes_for :line_item_options, :allow_destroy => true
您必须添加_destroy在您的PARAMS:
def line_item_params
params.require(:line_item).permit(line_item_options_attributes: [ ......., :_destroy])
end