PageRenderTime 54ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/rails30-ruby19/rails/classes/ActiveRecord/Callbacks.html

https://github.com/jparker/api-doc-mirror
HTML | 387 lines | 320 code | 67 blank | 0 comment | 0 complexity | 57cfe5e498049ec5223176db5b602d95 MD5 | raw file
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  3. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  4. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  5. <head>
  6. <title>ActiveRecord::Callbacks</title>
  7. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  8. <link rel="stylesheet" href="../../css/reset.css" type="text/css" media="screen" />
  9. <link rel="stylesheet" href="../../css/main.css" type="text/css" media="screen" />
  10. <script src="../../js/jquery-1.3.2.min.js" type="text/javascript" charset="utf-8"></script>
  11. <script src="../../js/jquery-effect.js" type="text/javascript" charset="utf-8"></script>
  12. <script src="../../js/main.js" type="text/javascript" charset="utf-8"></script>
  13. </head>
  14. <body>
  15. <div class="banner">
  16. <h1>
  17. <span class="type">Module</span>
  18. ActiveRecord::Callbacks
  19. </h1>
  20. <ul class="files">
  21. <li><a href="../../files/activerecord/lib/active_record/callbacks_rb.html">activerecord/lib/active_record/callbacks.rb</a></li>
  22. </ul>
  23. </div>
  24. <div id="bodyContent">
  25. <div id="content">
  26. <div class="description">
  27. <h1>Active Record <a href="Callbacks.html">Callbacks</a></h1>
  28. <p>
  29. <a href="Callbacks.html">Callbacks</a> are hooks into the life cycle of an
  30. Active Record object that allow you to trigger logic before or after an
  31. alteration of the object state. This can be used to make sure that
  32. associated and dependent objects are deleted when <tt>destroy</tt> is
  33. called (by overwriting <tt>before_destroy</tt>) or to massage attributes
  34. before they&#8217;re validated (by overwriting <tt>before_validation</tt>).
  35. As an example of the callbacks initiated, consider the <tt>Base#save</tt>
  36. call for a new record:
  37. </p>
  38. <ul>
  39. <li>(-) <tt>save</tt>
  40. </li>
  41. <li>(-) <tt>valid</tt>
  42. </li>
  43. <li>(1) <tt>before_validation</tt>
  44. </li>
  45. <li>(-) <tt>validate</tt>
  46. </li>
  47. <li>(2) <tt>after_validation</tt>
  48. </li>
  49. <li>(3) <tt>before_save</tt>
  50. </li>
  51. <li>(4) <tt>before_create</tt>
  52. </li>
  53. <li>(-) <tt>create</tt>
  54. </li>
  55. <li>(5) <tt>after_create</tt>
  56. </li>
  57. <li>(6) <tt>after_save</tt>
  58. </li>
  59. <li>(7) <tt>after_commit</tt>
  60. </li>
  61. </ul>
  62. <p>
  63. Also, an <tt>after_rollback</tt> callback can be configured to be triggered
  64. whenever a rollback is issued. Check out
  65. <tt>ActiveRecord::Transactions</tt> for more details about
  66. <tt>after_commit</tt> and <tt>after_rollback</tt>.
  67. </p>
  68. <p>
  69. That&#8217;s a total of ten callbacks, which gives you immense power to
  70. react and prepare for each state in the Active Record life cycle. The
  71. sequence for calling <tt>Base#save</tt> for an existing record is similar,
  72. except that each <tt>_on_create</tt> callback is replaced by the
  73. corresponding <tt>_on_update</tt> callback.
  74. </p>
  75. <p>
  76. Examples:
  77. </p>
  78. <pre>
  79. class CreditCard &lt; ActiveRecord::Base
  80. # Strip everything but digits, so the user can specify &quot;555 234 34&quot; or
  81. # &quot;5552-3434&quot; or both will mean &quot;55523434&quot;
  82. before_validation(:on =&gt; :create) do
  83. self.number = number.gsub(/[^0-9]/, &quot;&quot;) if attribute_present?(&quot;number&quot;)
  84. end
  85. end
  86. class Subscription &lt; ActiveRecord::Base
  87. before_create :record_signup
  88. private
  89. def record_signup
  90. self.signed_up_on = Date.today
  91. end
  92. end
  93. class Firm &lt; ActiveRecord::Base
  94. # Destroys the associated clients and people when the firm is destroyed
  95. before_destroy { |record| Person.destroy_all &quot;firm_id = #{record.id}&quot; }
  96. before_destroy { |record| Client.destroy_all &quot;client_of = #{record.id}&quot; }
  97. end
  98. </pre>
  99. <h2>Inheritable callback queues</h2>
  100. <p>
  101. Besides the overwritable callback methods, it&#8217;s also possible to
  102. register callbacks through the use of the callback macros. Their main
  103. advantage is that the macros add behavior into a callback queue that is
  104. kept intact down through an inheritance hierarchy.
  105. </p>
  106. <pre>
  107. class Topic &lt; ActiveRecord::Base
  108. before_destroy :destroy_author
  109. end
  110. class Reply &lt; Topic
  111. before_destroy :destroy_readers
  112. end
  113. </pre>
  114. <p>
  115. Now, when <tt>Topic#destroy</tt> is run only <tt>destroy_author</tt> is
  116. called. When <tt>Reply#destroy</tt> is run, both <tt>destroy_author</tt>
  117. and <tt>destroy_readers</tt> are called. Contrast this to the following
  118. situation where the <tt>before_destroy</tt> methis is overriden:
  119. </p>
  120. <pre>
  121. class Topic &lt; ActiveRecord::Base
  122. def before_destroy() destroy_author end
  123. end
  124. class Reply &lt; Topic
  125. def before_destroy() destroy_readers end
  126. end
  127. </pre>
  128. <p>
  129. In that case, <tt>Reply#destroy</tt> would only run
  130. <tt>destroy_readers</tt> and <em>not</em> <tt>destroy_author</tt>. So, use
  131. the callback macros when you want to ensure that a certain callback is
  132. called for the entire hierarchy, and use the regular overwriteable methods
  133. when you want to leave it up to each descendant to decide whether they want
  134. to call <tt>super</tt> and trigger the inherited callbacks.
  135. </p>
  136. <p>
  137. <b>IMPORTANT:</b> In order for inheritance to work for the callback queues,
  138. you must specify the callbacks before specifying the associations.
  139. Otherwise, you might trigger the loading of a child before the parent has
  140. registered the callbacks and they won&#8217;t be inherited.
  141. </p>
  142. <h2>Types of callbacks</h2>
  143. <p>
  144. There are four types of callbacks accepted by the callback macros: Method
  145. references (symbol), callback objects, inline methods (using a proc), and
  146. inline eval methods (using a string). Method references and callback
  147. objects are the recommended approaches, inline methods using a proc are
  148. sometimes appropriate (such as for creating mix-ins), and inline eval
  149. methods are deprecated.
  150. </p>
  151. <p>
  152. The method reference callbacks work by specifying a protected or private
  153. method available in the object, like this:
  154. </p>
  155. <pre>
  156. class Topic &lt; ActiveRecord::Base
  157. before_destroy :delete_parents
  158. private
  159. def delete_parents
  160. self.class.delete_all &quot;parent_id = #{id}&quot;
  161. end
  162. end
  163. </pre>
  164. <p>
  165. The callback objects have methods named after the callback called with the
  166. record as the only parameter, such as:
  167. </p>
  168. <pre>
  169. class BankAccount &lt; ActiveRecord::Base
  170. before_save EncryptionWrapper.new
  171. after_save EncryptionWrapper.new
  172. after_initialize EncryptionWrapper.new
  173. end
  174. class EncryptionWrapper
  175. def before_save(record)
  176. record.credit_card_number = encrypt(record.credit_card_number)
  177. end
  178. def after_save(record)
  179. record.credit_card_number = decrypt(record.credit_card_number)
  180. end
  181. alias_method :after_find, :after_save
  182. private
  183. def encrypt(value)
  184. # Secrecy is committed
  185. end
  186. def decrypt(value)
  187. # Secrecy is unveiled
  188. end
  189. end
  190. </pre>
  191. <p>
  192. So you specify the object you want messaged on a given callback. When that
  193. callback is triggered, the object has a method by the name of the callback
  194. messaged. You can make these callbacks more flexible by passing in other
  195. initialization data such as the name of the attribute to work with:
  196. </p>
  197. <pre>
  198. class BankAccount &lt; ActiveRecord::Base
  199. before_save EncryptionWrapper.new(&quot;credit_card_number&quot;)
  200. after_save EncryptionWrapper.new(&quot;credit_card_number&quot;)
  201. after_initialize EncryptionWrapper.new(&quot;credit_card_number&quot;)
  202. end
  203. class EncryptionWrapper
  204. def initialize(attribute)
  205. @attribute = attribute
  206. end
  207. def before_save(record)
  208. record.send(&quot;#{@attribute}=&quot;, encrypt(record.send(&quot;#{@attribute}&quot;)))
  209. end
  210. def after_save(record)
  211. record.send(&quot;#{@attribute}=&quot;, decrypt(record.send(&quot;#{@attribute}&quot;)))
  212. end
  213. alias_method :after_find, :after_save
  214. private
  215. def encrypt(value)
  216. # Secrecy is committed
  217. end
  218. def decrypt(value)
  219. # Secrecy is unveiled
  220. end
  221. end
  222. </pre>
  223. <p>
  224. The callback macros usually accept a symbol for the method they&#8217;re
  225. supposed to run, but you can also pass a &#8220;method string&#8221;, which
  226. will then be evaluated within the binding of the callback. Example:
  227. </p>
  228. <pre>
  229. class Topic &lt; ActiveRecord::Base
  230. before_destroy 'self.class.delete_all &quot;parent_id = #{id}&quot;'
  231. end
  232. </pre>
  233. <p>
  234. Notice that single quotes (&#8217;) are used so the <tt>#{id}</tt> part
  235. isn&#8217;t evaluated until the callback is triggered. Also note that these
  236. inline callbacks can be stacked just like the regular ones:
  237. </p>
  238. <pre>
  239. class Topic &lt; ActiveRecord::Base
  240. before_destroy 'self.class.delete_all &quot;parent_id = #{id}&quot;',
  241. 'puts &quot;Evaluated after parents are destroyed&quot;'
  242. end
  243. </pre>
  244. <h2>The <tt>after_find</tt> and <tt>after_initialize</tt> exceptions</h2>
  245. <p>
  246. Because <tt>after_find</tt> and <tt>after_initialize</tt> are called for
  247. each object found and instantiated by a finder, such as
  248. <tt>Base.find(:all)</tt>, we&#8217;ve had to implement a simple performance
  249. constraint (50% more speed on a simple test case). Unlike all the other
  250. callbacks, <tt>after_find</tt> and <tt>after_initialize</tt> will only be
  251. run if an explicit implementation is defined (<tt>def after_find</tt>). In
  252. that case, all of the callback types will be called.
  253. </p>
  254. <h2><tt>before_validation*</tt> returning statements</h2>
  255. <p>
  256. If the returning value of a <tt>before_validation</tt> callback can be
  257. evaluated to <tt>false</tt>, the process will be aborted and
  258. <tt>Base#save</tt> will return <tt>false</tt>. If Base#save! is called it
  259. will raise a <a href="RecordInvalid.html">ActiveRecord::RecordInvalid</a>
  260. exception. Nothing will be appended to the errors object.
  261. </p>
  262. <h2>Canceling callbacks</h2>
  263. <p>
  264. If a <tt>before_*</tt> callback returns <tt>false</tt>, all the later
  265. callbacks and the associated action are cancelled. If an <tt>after_*</tt>
  266. callback returns <tt>false</tt>, all the later callbacks are cancelled. <a
  267. href="Callbacks.html">Callbacks</a> are generally run in the order they are
  268. defined, with the exception of callbacks defined as methods on the model,
  269. which are called last.
  270. </p>
  271. <h2><a href="Transactions.html">Transactions</a></h2>
  272. <p>
  273. The entire callback chain of a <tt>save</tt>, <tt>save!</tt>, or
  274. <tt>destroy</tt> call runs within a transaction. That includes
  275. <tt>after_*</tt> hooks. If everything goes fine a COMMIT is executed once
  276. the chain has been completed.
  277. </p>
  278. <p>
  279. If a <tt>before_*</tt> callback cancels the action a ROLLBACK is issued.
  280. You can also trigger a ROLLBACK raising an exception in any of the
  281. callbacks, including <tt>after_*</tt> hooks. Note, however, that in that
  282. case the client needs to be aware of it because an ordinary <tt>save</tt>
  283. will raise such exception instead of quietly returning <tt>false</tt>.
  284. </p>
  285. <h2>Debugging callbacks</h2>
  286. <p>
  287. To list the methods and procs registered with a particular callback, append
  288. <tt>_callback_chain</tt> to the callback name that you wish to list and
  289. send that to your class from the <a href="../Rails.html">Rails</a> console:
  290. </p>
  291. <pre>
  292. &gt;&gt; Topic.after_save_callback_chain
  293. =&gt; [#&lt;ActiveSupport::Callbacks::Callback:0x3f6a448
  294. @method=#&lt;Proc:0x03f9a42c@/Users/foo/bar/app/models/topic.rb:43&gt;, kind:after_save, identifiernil,
  295. options{}]
  296. </pre>
  297. </div>
  298. <div class="sectiontitle">Included Modules</div>
  299. <ul>
  300. <li>
  301. <a href="../Rails.html">Rails</a>
  302. START:includes
  303. </li>
  304. </ul>
  305. <div class="sectiontitle">Classes and Modules</div>
  306. <ul>
  307. <li><span class="type">MODULE</span> <a href="Callbacks/ClassMethods.html">ActiveRecord::Callbacks::ClassMethods</a></li>
  308. </ul>
  309. <div class="sectiontitle">Constants</div>
  310. <table border='0' cellpadding='5'>
  311. <tr valign='top'>
  312. <td class="attr-name">CALLBACKS</td>
  313. <td>=</td>
  314. <td class="attr-value">[ :after_initialize, :after_find, :after_touch, :before_validation, :after_validation, :before_save, :around_save, :after_save, :before_create, :around_create, :after_create, :before_update, :around_update, :after_update, :before_destroy, :around_destroy, :after_destroy, :after_commit, :after_rollback ]</td>
  315. </tr>
  316. </table>
  317. </div>
  318. </div>
  319. </body>
  320. </html>