Skip to content

Commit

Permalink
revised sections 9 to 14 of the validations guide
Browse files Browse the repository at this point in the history
  • Loading branch information
fxn committed Mar 10, 2009
1 parent d028374 commit a99faa8
Showing 1 changed file with 18 additions and 15 deletions.
33 changes: 18 additions & 15 deletions railties/guides/source/activerecord_validations_callbacks.textile
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@ Callbacks are methods that get called at certain moments of an object's lifecycl


h4. Callback Registration h4. Callback Registration


In order to use the available callbacks, you need to register them. You can do that by implementing them as an ordinary methods, and then using a macro-style class method to register then as callbacks. In order to use the available callbacks, you need to register them. You can do that by implementing them as ordinary methods, and then using a macro-style class method to register them as callbacks.


<ruby> <ruby>
class User < ActiveRecord::Base class User < ActiveRecord::Base
Expand All @@ -770,7 +770,7 @@ class User < ActiveRecord::Base


protected protected
def ensure_login_has_a_value def ensure_login_has_a_value
if self.login.nil? if login.nil?
self.login = email unless email.blank? self.login = email unless email.blank?
end end
end end
Expand All @@ -793,43 +793,43 @@ h3. Available Callbacks


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: 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:


h4. Creating and/or Updating an Object

* +before_validation+
* +after_validation+
* +before_save+
* INSERT OR UPDATE OPERATION
* +after_save+

h4. Creating an Object h4. Creating an Object


* +before_validation+
* +before_validation_on_create+ * +before_validation_on_create+
* +after_validation+
* +after_validation_on_create+ * +after_validation_on_create+
* +before_save+
* +before_create+ * +before_create+
* INSERT OPERATION * INSERT OPERATION
* +after_create+ * +after_create+
* +after_save+


h4. Updating an Object h4. Updating an Object


* +before_validation+
* +before_validation_on_update+ * +before_validation_on_update+
* +after_validation+
* +after_validation_on_update+ * +after_validation_on_update+
* +before_save+
* +before_update+ * +before_update+
* UPDATE OPERATION * UPDATE OPERATION
* +after_update+ * +after_update+
* +after_save+


h4. Destroying an Object h4. Destroying an Object


* +before_destroy+ * +before_destroy+
* DELETE OPERATION * DELETE OPERATION
* +after_destroy+ * +after_destroy+


h4. after_initialize and after_find h4. +after_initialize+ and +after_find+


The +after_initialize+ callback will be called whenever an Active Record object is instantiated, either by directly 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_initialize+ callback will be called whenever an Active Record object is instantiated, either by directly 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_find+ callback will be called whenever Active Record loads a record from the database. +after_find+ is called before +after_initialize+ if both are defined.


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. The +after_initialize+ and +after_find+ callbacks are a bit different from the others. They have no +before_*+ counterparts, and the only way to register them is by defining them as regular 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.


<ruby> <ruby>
class User < ActiveRecord::Base class User < ActiveRecord::Base
Expand Down Expand Up @@ -877,6 +877,7 @@ Additionally, the +after_find+ callback is triggered by the following finder met
* +all+ * +all+
* +first+ * +first+
* +find+ * +find+
* +find_all_by_<em>attribute</em>+
* +find_by_<em>attribute</em>+ * +find_by_<em>attribute</em>+
* +find_by_<em>attribute</em>!+ * +find_by_<em>attribute</em>!+
* +last+ * +last+
Expand All @@ -902,11 +903,13 @@ h3. Halting Execution


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. 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.


If any callback methods return +false+ or raise an exception, the execution chain will be halted and the desired operation will not complete. This is because the whole callback chain is wrapped in a transaction, and raising an exception or returning +false+ fires a database ROLLBACK. The whole callback chain is wrapped in a transaction. If any before callback method returns exactly +false+ or raises an exception the execution chain gets halted and a ROLLBACK is issued. After callbacks can only accomplish that by raising an exception.

WARNING. Raising an arbitrary exception may break code that expects +save+ and friends not to fail like that. The +ActiveRecord::Rollback+ exception is thought precisely to tell Active Record a rollback is going on. That one is internally captured but not reraised.


h3. Relational Callbacks h3. Relational Callbacks


Callbacks work through model relationships, and can even be defined by them. Let's take an example where a User has_many Posts. In our example, a User's Posts should be destroyed if the User is destroyed. So, we'll add an after_destroy callback to the User model by way of its relationship to the Post model. Callbacks work through model relationships, and can even be defined by them. Let's take an example where a user has many posts. In our example, a user's posts should be destroyed if the user is destroyed. So, we'll add an +after_destroy+ callback to the +User+ model by way of its relationship to the +Post+ model.


<ruby> <ruby>
class User < ActiveRecord::Base class User < ActiveRecord::Base
Expand Down

0 comments on commit a99faa8

Please sign in to comment.