首页 > 解决方案 > Rails - collection_check_boxes 未触发连接模型上的回调

问题描述

由于最初的问题没有达到目标,这里有一个重写的版本,它更好地描述了这个问题。

我有以下型号:

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 也会有一个子 Charge 模型。

在我的 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当使用表单助手创建 LineItemOption 时,after_create回调会按预期触发。但是,当使用相同的表单助手销毁 LineItemOption 时,不会触发回调。为了测试这一点,我使用has_many :charges, as: :chargeable, dependent: :destroy了 before_destroy 回调。在这两种情况下,回调都来自 rails 控制台,但不是 collection_check_boxes 表单助手。

查看服务器日志,我可以看到在 LineItemOption 上调用了 destroy 方法,该方法可以愉快地运行,而无需运行适当的回调

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助手的常见行为吗?

标签: ruby-on-railsruby

解决方案


很久以前,rails 中似乎有一个错误或某些东西,当您从关联https://github.com/rails/rails/issues/27099after_destroy中删除记录时,不会触发回调(我猜该选项取决于在那个回调上)。has_many :throughdependant: :destroy

您必须实施一些 hacky 解决方案,例如,在分配新的 line_items 之前,执行类似操作line_item.line_item_options.destroy_allline_item.line_item_options.each(&:destroy)通过手动触发 propper 回调然后更新记录来删除记录,以便 rails 可以创建新的关联而不会出现错误的破坏行为。


推荐阅读