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が削除されてから実行される.