class Order < ActiveRecord::Base + before_save :normalize_card_number, :if => :paid_with_card? +end
diff --git a/railties/doc/guides/html/activerecord_validations_callbacks.html b/railties/doc/guides/html/activerecord_validations_callbacks.html index 7936de209d060d357219a626ca7128db6e413b05..bdd5e723ea9313f7625a013ce1249d7494979761 100644 --- a/railties/doc/guides/html/activerecord_validations_callbacks.html +++ b/railties/doc/guides/html/activerecord_validations_callbacks.html @@ -292,6 +292,20 @@ ul#navMain {
Sometimes it will make sense to validate an object just when a given predicate is satisfied. You can do that by using the :if and :unless options, which can take a symbol, a string or a Ruby Proc. You may use the :if option when you want to specify when the validation should happen. If you want to specify when the validation should not happen, then you may use the :unless option.
You can associated the :if and :unless options with a symbol corresponding to the name of a method that will get called right before validation happens. This is the most commonly used option.
You can associate the :if and :unless options with a symbol corresponding to the name of a method that will get called right before validation happens. This is the most commonly used option.
class Order < ActiveRecord::Base + before_save :normalize_card_number, :if => :paid_with_card? +end
You can also use a string that will be evaluated using :eval and needs to contain valid Ruby code. You should use this option only when the string represents a really short condition.
class Order < ActiveRecord::Base + before_save :normalize_card_number, :if => "paid_with_card?" +end
Finally, it’s possible to associate :if and :unless with a Ruby Proc object. This option is best suited when writing short validation methods, usually one-liners.
class Order < ActiveRecord::Base + before_save :normalize_card_number, + :if => Proc.new { |order| order.paid_with_card? } +end
When writing conditional callbacks, it’s possible to mix both :if and :unless in the same callback declaration.
class Comment < ActiveRecord::Base + after_create :send_email_to_author, :if => :author_wants_emails?, + :unless => Proc.new { |comment| comment.post.ignore_comments? } +end
Here is a list with all the available Active Record callbacks, listed in the same order in which they will get called during the respective operations.
@@ -1156,7 +1216,7 @@ Readability, since your callback declarations will live at the beggining of your
@@ -1184,7 +1244,7 @@ Readability, since your callback declarations will live at the beggining of your
@@ -1212,7 +1272,7 @@ Readability, since your callback declarations will live at the beggining of your
@@ -1231,16 +1291,16 @@ Readability, since your callback declarations will live at the beggining of your
The before_destroy and after_destroy callbacks will only be called if you delete the model using either the destroy instance method or one of the destroy or destroy_all class methods of your Active Record class. If you use delete or delete_all no callback operations will run, since Active Record will not instantiate any objects, accessing the records to be deleted directly in the database.
The after_initialize callback will be called whenever an Active Record object is instantiated, either by direcly using new or when a record is loaded from the database. It can be useful to avoid the need to directly override your Active Record initialize method.
The after_find callback will be called whenever Active Record loads a record from the database. When used together with after_initialize it will run first, since Active Record will first read the record from the database and them create the model object that will hold it.
The after_initialize and after_find callbacks are a bit different from the others, since the only way to register those callbacks is by defining them as methods. If you try to register after_initialize or after_find using macro-style class methods, they will just be ignored. This behaviour is due to performance reasons, since after_initialize and after_find will both be called for each record found in the database, significantly slowing down the queries.
As you start registering new callbacks for your models, they will be queued for execution. This queue will include all your model’s validations, the registered callbacks and the database operation to be executed. However, if at any moment one of the before_create, before_save, before_update or before_destroy callback methods returns a boolean false (not nil) value, this execution chain will be halted and the desired operation will not complete: your model will not get persisted in the database, or your records will not get deleted and so on.
Sometimes the callback methods that you’ll write will be useful enough to be reused at other models. Active Record makes it possible to create classes that encapsulate the callback methods, so it becomes very easy to reuse them.
Here’s an example where we create a class with a after_destroy callback for a PictureFile model.
You can declare as many callbacks as you want inside your callback classes.
Active Record callbacks are a powerful feature, but they can pollute your model implementation with code that’s not directly related to the model’s purpose. In object-oriented software, it’s always a good idea to design your classes with a single responsibility in the whole system. For example, it wouldn’t make much sense to have a User model with a method that writes data about a login attempt to a log file. Whenever you’re using callbacks to write code that’s not directly related to your model class purposes, it may be a good moment to create an Observer.
An Active Record Observer is an object that links itself to a model and registers its methods for callbacks. Your model’s implementation remains clean, while you can reuse the code in the Observer to add behaviour to more than one model class. OK, you may say that we can also do that using callback classes, but it would still force us to add code to our model’s implementation.
class Auditor < ActiveRecord::Observer observe User, Registration, Invoice end
If you paid attention, you may be wondering where Active Record Observers are referenced in our applications, so they get instantiated and begin to interact with our models. For observers to work we need to register them somewhere. The usual place to do that is in our application’s config/environment.rb file. In this file there is a commented-out line where we can define the observers that our application should load at start-up.
You can uncomment the line with config.active_record.observers and change the symbols for the name of the observers that should be registered.
It’s also possible to register callbacks in any of the files living at config/environments/, if you want an observer to work only in a specific environment. There is not a config.active_record.observers line at any of those files, but you can simply add it.
By convention, you should always save your observers' source files inside app/models.