LoginSignup
8
0

More than 1 year has passed since last update.

has_manyのdependent: xxxが実行される前に、before_destroyを実行する方法

Last updated at Posted at 2023-03-17

この記事で説明したいこと

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

参考

8
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
0