Skip to content
Browse files

Added some text about AR callbacks

  • Loading branch information...
1 parent b60971a commit c6e5ffbc5c5df14111d8925c82f143da73f6271b @cassiomarques cassiomarques committed Nov 18, 2008
View
104 railties/doc/guides/html/activerecord_validations_callbacks.html
@@ -270,6 +270,21 @@ <h2 id="site_title_tagline">Sustainable productivity for web-application develop
<a href="#_using_the_tt_errors_tt_collection">Using the <tt>errors</tt> collection</a>
</li>
<li>
+ <a href="#_callbacks">Callbacks</a>
+ <ul>
+
+ <li><a href="#_callbacks_registration">Callbacks registration</a></li>
+
+ <li><a href="#_registering_callbacks_by_overriding_the_callback_methods">Registering callbacks by overriding the callback methods</a></li>
+
+ <li><a href="#_registering_callbacks_by_using_macro_style_class_methods">Registering callbacks by using macro-style class methods</a></li>
+
+ </ul>
+ </li>
+ <li>
+ <a href="#_callbacks_that_get_triggered_when_an_objects_is_saved">Callbacks that get triggered when an objects is saved</a>
+ </li>
+ <li>
<a href="#_changelog">Changelog</a>
</li>
</ol>
@@ -860,7 +875,94 @@ <h2 id="_using_the_tt_errors_tt_collection">7. Using the <tt>errors</tt> collect
person<span style="color: #990000">.</span>errors <span style="font-style: italic"><span style="color: #9A1900"># =&gt; nil</span></span>
</tt></pre></div></div>
</div>
-<h2 id="_changelog">8. Changelog</h2>
+<h2 id="_callbacks">8. Callbacks</h2>
+<div class="sectionbody">
+<div class="para"><p>Callbacks are methods that get called at certain moments of an object's lifecycle. With callbacks it's possible to write code that will run whenever an Active Record object is created, saved, updated, deleted or loaded from the database.</p></div>
+<h3 id="_callbacks_registration">8.1. Callbacks registration</h3>
+<div class="para"><p>In order to use the available callbacks, you need to registrate them. There are two ways of doing that.</p></div>
+<h3 id="_registering_callbacks_by_overriding_the_callback_methods">8.2. Registering callbacks by overriding the callback methods</h3>
+<div class="para"><p>You can specify the callback method direcly, by overriding it. Let's see how it works using the <tt>before_validation</tt> callback, which will surprisingly run right before any validation is done.</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> User <span style="color: #990000">&lt;</span> ActiveRecord<span style="color: #990000">::</span>Base
+ validates_presence_of <span style="color: #990000">:</span>login<span style="color: #990000">,</span> <span style="color: #990000">:</span>email
+
+ protected
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> before_validation
+ <span style="font-weight: bold"><span style="color: #0000FF">if</span></span> <span style="font-weight: bold"><span style="color: #0000FF">self</span></span><span style="color: #990000">.</span>login<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #0000FF">nil</span></span><span style="color: #990000">?</span>
+ <span style="font-weight: bold"><span style="color: #0000FF">self</span></span><span style="color: #990000">.</span>login <span style="color: #990000">=</span> email <span style="font-weight: bold"><span style="color: #0000FF">unless</span></span> email<span style="color: #990000">.</span>blank?
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+</tt></pre></div></div>
+<h3 id="_registering_callbacks_by_using_macro_style_class_methods">8.3. Registering callbacks by using macro-style class methods</h3>
+<div class="para"><p>The other way you can register a callback method is by implementing it as an ordinary method, and then using a macro-style class method to register it as a callback. The last example could be written like that:</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> User <span style="color: #990000">&lt;</span> ActiveRecord<span style="color: #990000">::</span>Base
+ validates_presence_of <span style="color: #990000">:</span>login<span style="color: #990000">,</span> <span style="color: #990000">:</span>email
+
+ before_validation <span style="color: #990000">:</span>ensure_login_has_a_value
+
+ protected
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> ensure_login_has_a_value
+ <span style="font-weight: bold"><span style="color: #0000FF">if</span></span> <span style="font-weight: bold"><span style="color: #0000FF">self</span></span><span style="color: #990000">.</span>login<span style="color: #990000">.</span><span style="font-weight: bold"><span style="color: #0000FF">nil</span></span><span style="color: #990000">?</span>
+ <span style="font-weight: bold"><span style="color: #0000FF">self</span></span><span style="color: #990000">.</span>login <span style="color: #990000">=</span> email <span style="font-weight: bold"><span style="color: #0000FF">unless</span></span> email<span style="color: #990000">.</span>blank?
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+</tt></pre></div></div>
+<div class="para"><p>The macro-style class methods can also receive a block. Rails best practices say that you should only use this style of registration if the code inside your block is so short that it fits in just one line.</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> User <span style="color: #990000">&lt;</span> ActiveRecord<span style="color: #990000">::</span>Base
+ validates_presence_of <span style="color: #990000">:</span>login<span style="color: #990000">,</span> <span style="color: #990000">:</span>email
+
+ before_create <span style="color: #FF0000">{</span><span style="color: #990000">|</span>user<span style="color: #990000">|</span> user<span style="color: #990000">.</span>name <span style="color: #990000">=</span> user<span style="color: #990000">.</span>login<span style="color: #990000">.</span>capitalize <span style="font-weight: bold"><span style="color: #0000FF">if</span></span> user<span style="color: #990000">.</span>name<span style="color: #990000">.</span>blank?<span style="color: #FF0000">}</span>
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+</tt></pre></div></div>
+<div class="para"><p>In Rails, the preferred way of registering callbacks is by using macro-style class methods. The main advantages of using macro-style class methods are:</p></div>
+<div class="ilist"><ul>
+<li>
+<p>
+You can add more than one method for each type of callback. Those methods will be queued for execution at the same order they were registered.
+</p>
+</li>
+<li>
+<p>
+Readability, since your callback declarations will live at the beggining of your models' files.
+</p>
+</li>
+</ul></div>
+<div class="admonitionblock">
+<table><tr>
+<td class="icon">
+<img src="./images/icons/caution.png" alt="Caution" />
+</td>
+<td class="content">Remember to always declare the callback methods as being protected or private. These methods should never be public, otherwise it will be possible to call them from code outside the model, violating object encapsulation and exposing implementation details.</td>
+</tr></table>
+</div>
+</div>
+<h2 id="_callbacks_that_get_triggered_when_an_objects_is_saved">9. Callbacks that get triggered when an objects is saved</h2>
+<div class="sectionbody">
+<div class="ilist"><ul>
+<li>
+<p>
+<tt>before_validation</tt> will be triggered before any validation upon your object is done. You can use this callback to change the object's state so it becames valid.
+</p>
+</li>
+</ul></div>
+</div>
+<h2 id="_changelog">10. Changelog</h2>
<div class="sectionbody">
<div class="para"><p><a href="http://rails.lighthouseapp.com/projects/16213/tickets/26-active-record-validations-and-callbacks">http://rails.lighthouseapp.com/projects/16213/tickets/26-active-record-validations-and-callbacks</a></p></div>
</div>
View
73 railties/doc/guides/source/activerecord_validations_callbacks.txt
@@ -477,6 +477,79 @@ person.errors.clear
person.errors # => nil
------------------------------------------------------------------
+== Callbacks
+
+Callbacks are methods that get called at certain moments of an object's lifecycle. With callbacks it's possible to write code that will run whenever an Active Record object is created, saved, updated, deleted or loaded from the database.
+
+=== Callbacks registration
+
+In order to use the available callbacks, you need to registrate them. There are two ways of doing that.
+
+=== Registering callbacks by overriding the callback methods
+
+You can specify the callback method direcly, by overriding it. Let's see how it works using the +before_validation+ callback, which will surprisingly run right before any validation is done.
+
+[source, ruby]
+------------------------------------------------------------------
+class User < ActiveRecord::Base
+ validates_presence_of :login, :email
+
+ protected
+ def before_validation
+ if self.login.nil?
+ self.login = email unless email.blank?
+ end
+ end
+end
+------------------------------------------------------------------
+
+=== Registering callbacks by using macro-style class methods
+
+The other way you can register a callback method is by implementing it as an ordinary method, and then using a macro-style class method to register it as a callback. The last example could be written like that:
+
+[source, ruby]
+------------------------------------------------------------------
+class User < ActiveRecord::Base
+ validates_presence_of :login, :email
+
+ before_validation :ensure_login_has_a_value
+
+ protected
+ def ensure_login_has_a_value
+ if self.login.nil?
+ self.login = email unless email.blank?
+ end
+ end
+end
+------------------------------------------------------------------
+
+The macro-style class methods can also receive a block. Rails best practices say that you should only use this style of registration if the code inside your block is so short that it fits in just one line.
+
+[source, ruby]
+------------------------------------------------------------------
+class User < ActiveRecord::Base
+ validates_presence_of :login, :email
+
+ before_create {|user| user.name = user.login.capitalize if user.name.blank?}
+end
+------------------------------------------------------------------
+
+In Rails, the preferred way of registering callbacks is by using macro-style class methods. The main advantages of using macro-style class methods are:
+
+* You can add more than one method for each type of callback. Those methods will be queued for execution at the same order they were registered.
+* Readability, since your callback declarations will live at the beggining of your models' files.
+
+CAUTION: Remember to always declare the callback methods as being protected or private. These methods should never be public, otherwise it will be possible to call them from code outside the model, violating object encapsulation and exposing implementation details.
+
+== Callbacks that get triggered when an objects is saved
+
+* +before_validation+ will be triggered before any validation upon your object is done. You can use this callback to change the object's state so it becames valid.
+
+
+
+
+
+
== Changelog

0 comments on commit c6e5ffb

Please sign in to comment.
Something went wrong with that request. Please try again.