Home > OS >  How do I run only before or after callbacks on an active record?
How do I run only before or after callbacks on an active record?

Time:08-05

Lets say I have the following class

class Foo < ActiveRecord::Base

before_save :before_callback_1, :before_callback_2, :before_callback_3
after_save :after_callback_1, :after_callback_2, :after_callback_3

end

I want to do something like:

foo = Foo.new

foo.run_before_save_callbacks
foo.update_columns(...)
foo.run_after_save_callbacks

Is there some active record method that allows me to do this or do I need to get a list of all the callbacks and filter them and run them manually?

CodePudding user response:

Instead of update_columns use update (or the alias update_attributes) to accomplish the update while also running callbacks. It would take the place of your 3 lines there.

#foo.run_before_save_callbacks # No need, already run by `update`.
foo.update(...)
#foo.run_after_save_callbacks  # No need, already run by `update`.

CodePudding user response:

You can trigger calling before_save and after_save callbacks like this:

foo.run_callbacks(:save) { foo.update_columns(...) }

See ActiveSupport::Callbacks.

CodePudding user response:

After reading your comment replies I have a better idea of what you're looking for. At the least, if you want to run before_save callbacks manually, you can get a list of them like this:

callbacks    = Foo._save_callbacks.select{ |callback| callback.kind == :before }
method_names = callbacks.map(&:filter)

Similarly for after_save callbacks:

callbacks    = Foo._save_callbacks.select{ |callback| callback.kind == :after }
method_names = callbacks.map(&:filter)

(I actually use this in minitest to make sure our models have the expected callbacks.)

  • Related