RubyOnRails provides us with many modjavascript:nicTemp();el callbacks around the object’s lifecycle when object is being created, updated or destroyed. For example: before_create, after_create, before_update, after_destroy etc. We use them to write & run our code around the object’s lifecycle by defining a method and associating them as one of the callbacks.
But then how can we make a piece of code execute as a callback for any another defined method except create, update, save and destroy? For example, let’s say we have a model Article and we want to execute something just before and after an article is being published without hooking into model’s before_save and after_save callbacks?
RubyOnRails or more precisely ActiveRecord provides us with a module ActiveModel::Callbacks, which allows us to define and register custom callbacks usingdefine_model_callbacks method. Lets have a look at the snippet below for the above scenario:
class Article
extend ActiveModel::Callbacks
define_model_callbacks :publish, :only => [:before, :after]
before_publish :check_publishability
after_publish :notify_subscribers
def publish
run_callbacks :publish do
puts "Publishing article..."
end
end
private
def check_publishability
puts "Checking publishability rules..."
end
def notify_subscribers
puts "Notifying subscribers..."
end
end
By default define_model_callbacks provides with all three callbacks i.e. before, after and around, but here in our example we have chosen to have just before and after callbacks by specifying a hash :only => [:after, :before] since only those two were needed. By using define_model_callbacks :publish, :only => [:after, :before] we got two new callback before_publish and after_publish, which we then used to register our callback methods.
So now when we will call publish method on an article object, check_publishabilitywill be executed as a before callback and notify_subscribers will be executed as an after callback for the publish method.
One point to note here is that the code in the publish method should be wrapped inrun_callback :publish block, so that when it is called on an object, its callbacks are executed too.
For the snippet above run_callback triggers before callbacks, yield the block given and then trigger after callbacks.
More information on define_model_callbacks can be found here.
>> article = Article.last >> article.publish Checking publishability rules... Publishing article... Notifying subscribers...
Source - http://vinsol.com/blog/2014/07/07/custom-model-callbacks-in-rubyonrails/
Post Your Ad Here
Comments