4

関連付けを通じて has_many にソフト削除を実装する最も簡単な方法は何ですか?

私が欲しいのは次のようなものです:

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

私は次の方法を使用したいCompany#users

  • フォームで機能し、既存の契約を破らないCompany#usersように、これは通常の関連付けである必要があります。
  • 会社にユーザーを追加すると、新しいStaffingwithactive: true作成されます。
  • 会社からユーザーを削除すると、既存のユーザーStaffingが更新されactive: falseます (現在は単に削除されます)。
  • 以前に削除されたユーザーを会社に追加すると (そのためStaffing#active == false)Staffingが に更新されactive: trueます。

メソッドをオーバーライドすることも考えましたCompany#users=が、関連付けを更新する方法が他にもあるため、実際には十分ではありません。

問題は、関連付けで説明された動作をどのように達成するかです。Company#users

ありがとう。

4

1 に答える 1

4

has_many :throughアソシエーションは、実際には単なる構文糖衣です。重いものを持ち上げる必要がある場合は、ロジックを分割し、適切なメソッドとスコープを提供することをお勧めします。コールバックをオーバーライドする方法を理解することは、この種のことにも役立ちます。

これにより、論理的な削除を開始し、その後にUser作成することができます。StaffingsUser

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
于 2012-05-04T05:27:25.163 に答える