作为循环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中继续),这样就形成了一个循环,最终你得到一个错误,#34;堆栈级别太深了。&#34;一个明显的解决方法是使用before_destroy
或after_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
。所以它形成了一个循环。
答案 0 :(得分:5)
如果周期的一侧只有一个回调,您可以用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
对我来说很有用,只要一方不需要其他回调来解雇。
答案 1 :(得分:4)
我也遇到了这个问题,并提出了一个不太好但可行的解决方案。从本质上讲,您只需使用与destroy_user
类似的destroy_staff
。
class User < ActiveRecord::Base
has_one: :staff
after_destroy :destroy_staff
def destroy_staff
staff.destroy if staff && !staff.destroyed?
end
end
class Staff < ActiveRecord::Base
belongs_to :user
after_destroy :destroy_user
def destroy_user
user.destroy if user && !user.destroyed?
end
end