acts_as_paranoidの挙動

acts_as_paranoidを使うことでレコードの論理削除が容易になる。さらにリレーションが設定されているときには関連する論理削除も行われるように設定できる。

けど、どのメソッドがどのような挙動を示すのかがいまいち不鮮明だったので、ざっくりと調べてみた。

モデル定義

GroupとPersonが1対多のリレーションを持っているとする(多対多の場合も同様だと思う)。

app/models/group.rb


class Group < ActiveRecord::Base
  acts_as_paranoid
  has_many :people, :dependent => :destroy
end

:dependent => :destroyは、レコードの削除時にリレーション先のレコードをどう処理するかを指定するオプションで、:destroyを指定するとリレーション先のレコードに対してdestroyメソッドを実行する。詳細はActiveRecord::Associations::ClassMethodsを参照。

app/models/person.rb


class Person < ActiveRecord::Base
  acts_as_paranoid
  belongs_to :group
end

挙動

Groupに対して削除系メソッドを実行したときに、それと関連するPersonがどうなるかを調べた。

なお、"!"がついているメソッドは破壊的メソッドなので、物理削除(DELETE文)が実行される。

クラスメソッド

メソッド Group 関連するPerson
Group.delete(id) 論理削除 変化無し
Group.destroy(id) 論理削除 論理削除
Group.delete_all 論理削除 変化無し
Group.delete_all! 物理削除 変化無し
Group.destroy_all 論理削除 論理削除

クラスメソッドはnamed_scopeなどとともにチェインすることが可能。

インスタンスメソッド

メソッド Group 関連するPerson
Group#delete 論理削除 変化無し
Group#destroy 論理削除 論理削除
Group#destroy! 物理削除 論理削除

Group#destroy!の挙動はちょっと中途半端。Personも含めて完全に物理削除したい場合は次のようにすれば良い。


group = Group.first
group.people.delete_all!
group.destroy!