In this conclusion to a five-part series that delves into the Rails framework's Active Record, you'll finish learning about validations, and take a look at callbacks. This article is excerpted from chapter five of the book Beginning Rails: From Novice to Professional, written by Jeffrey Allan Hardy, Cloves Carneiro Jr. and Hampton Catlin (Apress; ISBN: 1590596862).
Callbacks and the Active Record - Making Callbacks (Page 3 of 5 )
You will often want to have things happen during the life cycle of the model. Certain actions need to happen during certain events pertaining to a particular model. For instance, what if you wanted to send out an email to your administrator whenever someone canceled her account? Or perhaps you want to make sure to create a new model because some other model was also created. These are just a couple of examples of when you want certain actions in the life of a model to generate some associated actions.
To implement this, Active Record has callbacks. Six callbacks are commonly used in Active Record models:
before_create
after_create
before_save
after_save
before_destroy
after_destroy
As you can see, the names of the Rails callbacks describe their purpose. When you create a method with any of these names in your model, the method will be called automatically by the model during the time that the name suggests. For instance, if you make abefore_savemethod, that method will be called every time the model object is saved.
Any callback that starts withbefore_can stop the execution chain if it returnsfalse. For instance, if you were to define the followingbefore_create, you would ensure that this model object would never be created.
def before_create false end
This can be a “gotcha” later if you are doing something like an assignment offalseto a variable. If you’re ever confused why a model won’t save, check your before filters.
In our events application, we would like to make sure that when a user creates an event, that user automatically become an attendee. To set this up, we will add anafter_createmethod to theEventclass that will automatically make the user join the list of attendees when that user creates an event. Add the method shown in Listing 5-25 to theEventmodel.
Listing 5-25. after_create Method, in app/models/event.rb
def after_create attendees << user end
We used the shortcut<<method to simply throw the model’s user into the list of attendees. Note that<< automatically saves if the parent object is saved. This is nice and simple, but we should probably use the pattern as we did forvalidatein Listing 5-19, where we passed in a symbol that references the method to run when the validation was performed. This helps keep the code readable and easier to augment in the future, since we can supply an arbitrary number of methods to run on a callback, separated by a comma. We’ll name the methodensure_owner_attendsand tell Active Record to run it after a record is created, as shown in Listing 5-26.
Listing 5-26.ensure_owner_attends Method Specified As an after_create Callback, in app/models/event.rb
after_create :ensure_owner_attends
def ensure_owner_attends attendees << user end
We’re doing a bit more error checking this time and making sure that the user isn’t already attending. This is so we can use this method more than once without breaking anything. Then we simply tellafter_createon which method to call back.
Active Record provides many more callbacks than we’ve mentioned here, but those listed at the beginning of this section are the ones that we find ourselves using often. Some of the others are used in extremely rare cases (for instance,after_initialize, which is called after an object is initialized). These callbacks can help you with just about anything you need to do during the life cycle of a model. They are part of “smart” models, which know how to deal with their own birth, life, and death.