acts_as_paranoidとhas_many :throughでちょいはまる
データの削除を削除キーでしてくれるプラグインacts_as_paranoidですが、
has_many :throughを同時に使ってちょっとはまったんでメモ。
groupsテーブルとmembersテーブルが中間テーブルAssociationsで
has_many :throughを用いて、多対多の関係にあるとき、RailsのModelでは
#Grouop model class Group < ActiveRecord::Base has_many :associations has_many :members, :through => :associations end #Member model class Member < ActiveRecord::Base has_many :associations has_many :groups, :through => :associations end #Association model class Association < ActiveRecord::Base belongs_to :group belongs_to :member end
という感じになりますが、
このとき中間テーブルにacts_as_paranoidを
#Association model class Association < ActiveRecord::Base belongs_to :group belongs_to :member acts_as_paranoid end
って感じに設定してるとき、GroupとMemberの関連をなくすために
Associationの関連部分をdestroyしても、関連がなくなりません。
それは、Associationをfindしたら、削除されてるように見えますが、
実際は、データとして残ってる(acts_as_paranoidのおかげ)ので、
もしid=1のグループのユーザとの関連を削除していたとしても、
Group.find(1).users
は削除前の値を返します。
これを改善するためには、以下のようにGroupとMemberモデルを設定します。
#Grouop model class Group < ActiveRecord::Base has_many :associations # 変更箇所 has_many :members, :through => :associations, :conditions => "associations.deleted_at IS NULL" end #Member model class Member < ActiveRecord::Base has_many :associations # 変更箇所 has_many :groups, :through => :associations, :conditions => "associations.deleted_at IS NULL" end #Association model class Association < ActiveRecord::Base belongs_to :group belongs_to :member acts_as_paranoid end
これで、削除したやつは除いた値が得られます。
まぁ明示的に、acts_as_paranoidがやってる処理を書いてるだけですけど。