class Foo < ActiveRecord::Base
has_many :bars, dependent: :destroy
before_destroy :do_something
def do_something
return if bars.blank?
bars.map &:somethig_cool
end
end
このように, has_many(has_one)な関係をものをbefore_destroyで使うには注意が必要. 上の例だとbefore_destroyの前にbarsは削除されてしまうので, bars.blank?は必ず真になりbars.map &:somethig_coolは永久に実行されない.
これを避けるには以下のようにする.
class Foo < ActiveRecord::Base
before_destroy :do_something
has_many :bars, dependent: :destroy
# 以下略
before_destroyとhas_manyの順番を逆にしただけだが, これで期待通りの挙動(before_destroyの後にbarsを削除)になる.
なのでこのようなときはObserverは使えない.
class FooObserver < ActiveRecord::Observer
def before_destroy foo
return if foo.bars.blank?
foo.bars.map &:somethig_cool
end
end
上のbefore_destroyはbarsが削除されてから実行される.