作为循环 dependent: :destroy 问题的示例:

class User < ActiveRecord::Base
  has_one: :staff, dependent: :destroy
end

class Staff < ActiveRecord::Base
  belongs_to :user, dependent: :destroy
end

如果我调用 user.destroy ,关联的 staff 也应该被销毁。相反,调用 staff.destroy 也应该销毁关联的 user

这在 Rails 3.x 中效果很好,但在 Rails 4.0 中行为发生了变化(并在 4.1 中继续),从而形成循环并最终出现错误,“堆栈级别太深”。一个明显的解决方法是使用 before_destroyafter_destroy 创建自定义回调来手动销毁关联的对象,而不是使用 dependent: :destroy 机制。甚至 issue in GitHub opened for this 的情况也有几个人推荐这种解决方法。

不幸的是,我什至无法使该解决方法起作用。这就是我所拥有的:
class User < ActiveRecord::Base
  has_one: :staff

  after_destroy :destroy_staff

  def destroy_staff
    staff.destroy if staff and !staff.destroyed?
  end
end

这不起作用的原因是 staff.destroyed? 总是返回 false 。所以就形成了一个循环。

最佳答案

如果循环的一侧只有一个回调,则可以将 dependent: :destroy 之一替换为 dependent: :delete

class User < ActiveRecord::Base
  # delete prevents Staff's :destroy callback from happening
  has_one: :staff, dependent: :delete
  has_many :other_things, dependent: :destroy
end

class Staff < ActiveRecord::Base
  # use :destroy here so that other_things are properly removed
  belongs_to :user, dependent: :destroy
end

只要一侧不需要其他回调来触发,对我来说效果很好。

关于ruby-on-rails - 是否有 Rails 4 循环依赖 : :destroy workaround?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23208579/

10-13 02:11