ruby-on-rails - 是否有 Rails 4 循环依赖 : :destroy workaround?

标签 ruby-on-rails ruby-on-rails-3 ruby-on-rails-4 ruby-on-rails-4.1

以通函 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_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 .于是就形成了一个循环。

最佳答案

如果循环的一侧只有一个回调,您可以替换 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/

相关文章:

ruby-on-rails - 阻止其他登录用户访问 'edit' 页面

ruby-on-rails - 将变量从一个 Action 传递到另一个 Action

ruby-on-rails - 使用 Twitter Bootstrap 编写此布局的提示

ruby-on-rails-4 - Rails/ unicorn 错误: can't read secret_key_base and secret_token from "config/secrets.yml"

ruby-on-rails - 事件记录迁移 Rails 4 中的 has_many、belongs_to 关系

ruby-on-rails - NoMethodError in Pages#home undefined method `environment' for nil :NilClass

javascript - rails 5.2 : Issue with jquery-rails

ruby-on-rails - 清理 Controller 以加速应用程序

css - 如何从数据库中获取属性值并应用于表单

ruby-on-rails - 覆盖用于在 Rails 4 中创建表的默认 ActiveRecord 迁移