when is around_create callback code executed, in what situations we should use it?
A classic use-case for the "around" filters is to measure performance, or log or do other state monitoring or modification.
Besides Tom Harrison Jr's answer about logging and monitoring, I'm finding that the key differentiator is to gain control over whether or not the operation runs at all. Otherwise, you can implement your own before_*
and after_*
callbacks to do the same thing.
Take around_update
, for example. Let's say you have a case where you don't want the update to run. For example, I'm building a gem that saves drafts in another drafts
table but doesn't save certain updates to the "master" table.
around_update :save_update_for_draft
private
def save_update_for_draft
yield if update_base_record?
end
The details of the update_base_record?
method referenced here don't really matter. You can see that the update operation simply won't run if that method doesn't evaluate to true
.
Had this question, too, and have now found the answer: around_create
allows you to basically do both a before_create
and an after_create
in one method. You have to use yield
to execute the save in between.
class MyModel < ActiveRecord::Base
around_create :my_callback_method
private
def my_call_back_method
# do some "before_create" stuff here
yield # this makes the save happen
# do some "after_create" stuff here
end
end
Simpler and neat explanation about around callback I found, is given below
The around_* callback is called around the action and inside the before_* and after_* actions. For example:
class User
def before_save
puts 'before save'
end
def after_save
puts 'after_save'
end
def around_save
puts 'in around save'
yield # User saved
puts 'out around save'
end
end
User.save
before save
in around save
out around save
after_save
=> true
Originally posted here
Just found one use case for me:
Imagine a situation with polymorphic watcher and the watcher in some cases needs to perform action before save and in other cases after it.
With around filter you can capture save action in a block and run it when you need.
class SomeClass < ActiveRecord::Base
end
class SomeClassObserver < ActiveRecord::Observer
def around_create(instance, &block)
Watcher.perform_action(instance, &block)
end
end
# polymorphic watcher
class Watcher
def perform_action(some_class, &block)
if condition?
Watcher::First.perform_action(some_class, &block)
else
Watcher::Second.perform_action(some_class, &block)
end
end
end
class Watcher::First
def perform_action(some_class, &block)
# update attributes
some_class.field = "new value"
# save
block.call
end
end
class Watcher::Second
def perform_action(some_class, &block)
# save
block.call
# Do some stuff with id
Mailer.delay.email( some_class.id )
end
end
around_create
is called when a model with the new?
flag is saved. It can be used to add data to add/change values of the model, call other methods, etc... I cannot thnk of a specific use case for this call-back but it completes a set of "before, after, around" call-backs for the create action. There is a similar "before, after, around" call back set for the find, update, save, and delete events.