acts_as_paranoidとjoinsの注意点

railsで論理削除を行うときに使うプラグインacts_as_paranoid」を使用するとき注意することがあります。

modelにacts_as_paranoidを組み込み、通常の検索を行うと次のようなSQLが発行されます。

e = Employee.scoped
SELECT "employees".* FROM "employees" WHERE (employees.deleted_at IS NULL)

しかし、同じくacts_as_paranoidを組み込んだモデルをjoinしてみるとdeleted_atが考慮されないSQLが発行されるようです。

e = Employee.scoped.joins(:user)
SELECT "employees".* 
FROM "employees" 
INNER JOIN "users" ON "employees"."id" = "users"."employee_id" 
WHERE (employees.deleted_at IS NULL)

と、いうことでwhereでdeleted_atのチェックを追加してやりましょう。

先日「削除フラグのはなし」というスライドを見たんですが、O/Rマッパーとして削除フラグを実装するのもなかなか大変なんだろうなぁと思いました。