如何从任一端销毁双向 has_one 关联?

问题描述 投票:0回答:2

这是我的模型:

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
开始工作。

如何从任一端销毁左-中-右关联?

ruby-on-rails activerecord rails-activerecord
2个回答
1
投票

我找到了一个解决方案:在

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

我不知道这是否是规范的方法。


0
投票

根据 ActiveRecord 文档这里,它说:

注意 :dependent 是使用 Rails 的回调系统实现的, 它通过按顺序处理回调来工作。因此,其他 在 :dependent 选项之前或之后声明的回调可以 影响它的作用。

因此,由于我们在模型末尾声明了

belongs_to :right, dependent: :destroy
,因此它会处理在此之前声明的其他回调。但对于左侧,它不处理后回调。

在这种情况下,我认为创建

before_destroy
方法是处理问题的最佳方法。

© www.soinside.com 2019 - 2024. All rights reserved.