この記事で説明したいこと
before_destoryのprependオプションについて
背景
has_many :hogehoges, dependent: destroy
となっているhogehoges
がある。
このとき、親のレコードの削除に伴い、紐づくhogehoges
がdestroyされる前に行いたい処理があった。
例えば、
class Like < ApplicationRecord
module Likable
extend ActiveSupport::Concern
included do
has_many :likes, dependent: :destroy
end
end
end
class Article < ApplicationRecord
include Like::Likable
before_destroy :logging_final_likes
def logging_final_likes
puts likes.size
end
end
想定としては、logging_final_likes
を実行したあとに、likes
がdestroyされてほしかった。
しかし、これを実行してみると、logging_final_likes
は0になり、destroy前に実行されていないことが分かった。
以下のドキュメントによると、before_destroyよりも先にdestroyが実行されているらしい。(ただし、transactionは同じ)
これを回避するには、prepend: true
オプションがあり、これをbefore_destoryにつけると動きました。
class Article < ApplicationRecord
include Like::Likable
- before_destroy :logging_final_likes
+ before_destroy :logging_final_likes, prepend: true
def logging_final_likes
puts likes.size
end
end