通过关联对has_many进行软删除

时间:2012-05-04 01:44:47

标签: ruby-on-rails ruby activerecord orm associations

通过关联在has_many上实施软删除的最简单方法是什么?

我想要的是这样的:

class Company > ActiveRecord::Base
  has_many :staffings
  has_many :users, through: :staffings, conditions: {staffings: {active: true}}
end

我想以下列方式使用Company#users

  • Company#users应该是正常关联,以便与表单一起使用,并且不会破坏现有合同。
  • 向公司添加用户时,新的Staffing active: true 已创建
  • 从公司移除用户时,现有的Staffing已更新active: false(目前刚被删除)。
  • 以前删除的用户添加到公司时(以便Staffing#active == falseStaffing更新为active: true

我考虑过覆盖Company#users=方法,但它确实不够好,因为还有其他方法可以更新关联。

所以问题是:如何在Company#users关联上实现解释的行为?

感谢。

1 个答案:

答案 0 :(得分:4)

has_many :through关联实际上只是语法糖。当你需要做繁重的工作时,我会建议拆分逻辑并提供适当的方法和范围。了解如何覆盖callbacks对于此类事情也很有用。

这将让您开始使用User上的软删除并在Staffings之后创建User

class Company < ActiveRecord::Base
  has_many :staffings
  has_many :users, through: :staffings, conditions: ['staffings.active = ?', true]
end

class Staffing < ActiveRecord::Base
  belongs_to :company
  has_one :user
end

class User < ActiveRecord::Base
  belongs_to :staffing

  # after callback fires, create a staffing
  after_create {|user| user.create_staffing(active: true)}

  # override the destroy method since you 
  # don't actually want to destroy the User
  def destroy
    run_callbacks :delete do
      self.staffing.active = false if self.staffing
    end
  end
end