这是我的模型:
class Left < ApplicationRecord
has_one :middle, dependent: :destroy
has_one :right, through: :middle
end
class Middle < ApplicationRecord
belongs_to :left, dependent: :destroy
belongs_to :right, dependent: :destroy
end
class Right < ApplicationRecord
has_one :middle, dependent: :destroy
has_one :left, through: :middle
end
我希望
left.destroy
也摧毁它的middle
和它的right
。同样,我希望 right.destroy
摧毁它的 middle
和它的 left
。
通过上述设置,
right.destroy
可以执行我想要的操作,但left.destroy
不会破坏其right
。
但是,如果我颠倒
Middle
的 belongs_to
声明的顺序,则 right.destroy
停止工作,而 left.destroy
开始工作。
如何从任一端销毁左-中-右关联?
我找到了一个解决方案:在
Middle
中,从 :dependent
声明中删除 belongs_to
选项,并添加一个 after_destroy
回调,该回调显式销毁 left
和 right
关联对象。
class Middle < ApplicationRecord
belongs_to :left
belongs_to :right
after_destroy :destroy_associated
def destroy_associated
left.destroy
right.destroy
end
end
我不知道这是否是规范的方法。
根据 ActiveRecord 文档这里,它说:
注意 :dependent 是使用 Rails 的回调系统实现的, 它通过按顺序处理回调来工作。因此,其他 在 :dependent 选项之前或之后声明的回调可以 影响它的作用。
因此,由于我们在模型末尾声明了
belongs_to :right, dependent: :destroy
,因此它会处理在此之前声明的其他回调。但对于左侧,它不处理后回调。
在这种情况下,我认为创建
before_destroy
方法是处理问题的最佳方法。