An ActiveRecord model object experiences different states during its life cycle. Typically, it starts with creation, experiences several modification, saved to database and finally gets destroyed. We can write callbacks (ruby methods) that will be triggered upon each state change of model objects.
Callbacks are just ruby methods. Then what's callback class? A Callback class is just a group of methods where you can put your callback handlers and thus they can be shared among different models.
Let's say we have an Dog class, which has an instance variable called favorite_food. The table dogs has an attribute called name. What we want is whenever an Dog object is initialized, values will be assigned to favorite_food and name.
class Dog attr_accessor :favorite_food end
We need to create a callback class. Let's call it SharedCallbacks. And we need to define a method called after_initialize, which is the same name of the event we want it to handle.
class SharedCallbacks def after_initialize(model) model.favorite_food = 'meat' model.name = 'This is a dog' end end
The parameter "model" is the object on which the callback method will have effect on, which in this case is any Dog object.
Back to Dog class, now what we need to do is to create a SharedCallbacks object and hook it with the after_initialize declaration.
class Dog attr_accessor :favorite_food after_initialize SharedCallbacks.new end
So whenever a Dog object is initialized, an new SharedCallbacks object is created and the corresponding callback method, which is after_initialize in this case, is called using the Dog object as the single parameter. As a result, the Dog object's favorite_food and name are set to the desired values.
Now let's add another requirement, whenever a record is found in database, its name will be set to 'This is a cat'. What we need to do is define a after_find method in SharedCallbacks class and hook one of its object with the after_find callback declaration in Dog class.
class SharedCallbacks def after_initialize(model) model.favorite_food = 'meat' model.name = 'This is a dog' end def after_find(model) model.name = 'This is a cat' end end
class Dog attr_accessor :favorite_food after_initialize SharedCallbacks.new after_find SharedCallbacks.new end
If we retrieve a record from database and look into it, we're gonna find that its name is set to 'This is a dog', NOT 'This is a cat'. That's because the after_initialize callback is always invoked after after_find. In the book Agile Web Development with Rails, there is a complete order in which callbacks are invoked, if they are declared of course.
No comments:
Post a Comment