作为循环依赖的示例::destroy issue:
class User < ActiveRecord::Base has_one: :staff,dependent: :destroy end class Staff < ActiveRecord::Base belongs_to :user,dependent: :destroy end
如果我打电话给user.destroy,相关人员也应该被销毁.相反,调用staff.destroy也应该销毁相关联的用户.
这在Rails 3.x中工作得很好,但是Rails 4.0中的行为发生了变化(并在4.1中继续),从而形成一个循环,最终会出现“堆栈级别太深”的错误.一个明显的解决方法是使用before_destroy或after_destroy创建自定义回调,以手动销毁关联的对象,而不是使用从属::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.所以它形成一个循环.
解决方法
如果循环的一侧只有一个回调,则可以用依赖关系替换其中的一个::destroy与depend::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
为我工作很好,只要一方不需要其他回调来开火.