🐥
ActiveRecord の around_destroy と dependent: :destroy の呼び出し順
あんまりないと思うんですが Model で設定した around_destroy
が dependent: :destroy
で削除されるレコードに依存している場合に呼び出し順に注意する必要があります。
例えば以下のように dependent: :destroy
-> around_destroy
の順で定義した場合に意図する動きになりません。
class User < ActiveRecord::Base
has_many :comments, dependent: :destroy
around_destroy :around_destroy
def around_destroy
# 先に値を取得しておいて
comments = Comment.where(user_id: id).pluck(:text)
yield
# おわったら出力する
# が、これだとうまく動かない
pp comments
# => []
end
end
user = User.create(name: "homu")
user.comments.create(text: "はい")
user.comments.create(text: "Yes")
user.comments.create(text: "わかりました")
# このタイミングで user に紐づく comments が出力してほしい
user.destroy!
これは around_destroy
よりも先に dependent: :destroy
でレコードが削除されてしまっているからです。
こういう場合は先に around_destroy
を定義することで回避することができます。
class User < ActiveRecord::Base
around_destroy :around_destroy
def around_destroy
comments = Comment.where(user_id: id).pluck(:text)
yield
pp comments
# => ["はい", "Yes", "わかりました"]
end
# around_destroy よりも後で has_many を定義する
has_many :comments, dependent: :destroy
end
user = User.create(name: "homu")
user.comments.create(text: "はい")
user.comments.create(text: "Yes")
user.comments.create(text: "わかりました")
user.destroy!
コールバックでは呼び出し順に注意しましょう。
Discussion