New To Blue
New To Blue

Reputation: 107

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

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?

Upvotes: 0

Views: 1227

Answers (3)

spickermann
spickermann

Reputation: 106782

You can trigger calling before_save and after_save callbacks like this:

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

See ActiveSupport::Callbacks.

Upvotes: 2

BenFenner
BenFenner

Reputation: 1068

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.)

Upvotes: 1

BenFenner
BenFenner

Reputation: 1068

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`.

Upvotes: 0

Related Questions