👋
ActiveRecord のコールバックを明示的に呼び出す
ActiveRecord のコールバックを明示的に呼び出したかたので覚書。
次のように #run_callbacks
に呼び出したいイベントを渡すことで任意のコールバックを明示的に発火することができます。
class User < ActiveRecord::Base
before_create -> { puts "before create" }
after_create -> { puts "after create" }
before_save -> { puts "before save" }
after_save -> { puts "after save" }
end
user = User.new
user.run_callbacks(:create)
puts
user.run_callbacks(:save)
__END__
output:
before create
after create
before save
after save
こんな感じで create
や save
のコールバックを呼び出すことができます。
#run_callbacks
にブロックを渡したときの挙動
#run_callbacks
にブロックを渡した場合 before
と after
間でそのブロックが呼び出されます。
class User < ActiveRecord::Base
before_save -> { puts "before save" }
after_save -> { puts "after save" }
end
user = User.new
user.run_callbacks(:save) { puts "saving" }
__END__
output:
before save
saving
after save
このときに注意する必要があるのは『ブロックの戻り値が false
の場合はその後の処理は中断され after_xxx
は呼びされない』という点です。
class User < ActiveRecord::Base
before_save -> { puts "before save" }
after_save -> { puts "after save" }
end
user = User.new
# false を返すと after_save は呼ばれない
user.run_callbacks(:save) { false }
__END__
output:
before save
また nil
を返した場合は中断されずに after_save
が呼び出されます。
class User < ActiveRecord::Base
before_save -> { puts "before save" }
after_save -> { puts "after save" }
end
user = User.new
# nil を返すと after_save は呼ばれる
user.run_callbacks(:save) { nil }
__END__
output:
before save
after save
いわゆる 偽
かどうかで判定してるわけではなくて false
の場合は、で判定しているみたいですね。
Discussion