diff options
Diffstat (limited to 'activerecord/lib/active_record/callbacks.rb')
-rw-r--r-- | activerecord/lib/active_record/callbacks.rb | 53 |
1 files changed, 30 insertions, 23 deletions
diff --git a/activerecord/lib/active_record/callbacks.rb b/activerecord/lib/active_record/callbacks.rb index 3027ce928e..bfedc4af3f 100644 --- a/activerecord/lib/active_record/callbacks.rb +++ b/activerecord/lib/active_record/callbacks.rb @@ -1,11 +1,11 @@ module ActiveRecord - # = Active Record Callbacks + # = Active Record \Callbacks # - # Callbacks are hooks into the life cycle of an Active Record object that allow you to trigger logic + # \Callbacks are hooks into the life cycle of an Active Record object that allow you to trigger logic # before or after an alteration of the object state. This can be used to make sure that associated and - # dependent objects are deleted when +destroy+ is called (by overwriting +before_destroy+) or to massage attributes - # before they're validated (by overwriting +before_validation+). As an example of the callbacks initiated, consider - # the <tt>Base#save</tt> call for a new record: + # dependent objects are deleted when {ActiveRecord::Base#destroy}[rdoc-ref:Persistence#destroy] is called (by overwriting +before_destroy+) or + # to massage attributes before they're validated (by overwriting +before_validation+). + # As an example of the callbacks initiated, consider the {ActiveRecord::Base#save}[rdoc-ref:Persistence#save] call for a new record: # # * (-) <tt>save</tt> # * (-) <tt>valid</tt> @@ -20,7 +20,7 @@ module ActiveRecord # * (7) <tt>after_commit</tt> # # Also, an <tt>after_rollback</tt> callback can be configured to be triggered whenever a rollback is issued. - # Check out <tt>ActiveRecord::Transactions</tt> for more details about <tt>after_commit</tt> and + # Check out ActiveRecord::Transactions for more details about <tt>after_commit</tt> and # <tt>after_rollback</tt>. # # Additionally, an <tt>after_touch</tt> callback is triggered whenever an @@ -31,7 +31,7 @@ module ActiveRecord # are instantiated as well. # # There are nineteen callbacks in total, which give you immense power to react and prepare for each state in the - # Active Record life cycle. The sequence for calling <tt>Base#save</tt> for an existing record is similar, + # Active Record life cycle. The sequence for calling {ActiveRecord::Base#save}[rdoc-ref:Persistence#save] for an existing record is similar, # except that each <tt>_create</tt> callback is replaced by the corresponding <tt>_update</tt> callback. # # Examples: @@ -193,8 +193,9 @@ module ActiveRecord # == <tt>before_validation*</tt> returning statements # # If the +before_validation+ callback throws +:abort+, the process will be - # aborted and <tt>Base#save</tt> will return +false+. If Base#save! is called it will raise a - # <tt>ActiveRecord::RecordInvalid</tt> exception. Nothing will be appended to the errors object. + # aborted and {ActiveRecord::Base#save}[rdoc-ref:Persistence#save] will return +false+. + # If {ActiveRecord::Base#save!}[rdoc-ref:Persistence#save!] is called it will raise a ActiveRecord::RecordInvalid exception. + # Nothing will be appended to the errors object. # # == Canceling callbacks # @@ -206,7 +207,8 @@ module ActiveRecord # == Ordering callbacks # # Sometimes the code needs that the callbacks execute in a specific order. For example, a +before_destroy+ - # callback (+log_children+ in this case) should be executed before the children get destroyed by the +dependent: destroy+ option. + # callback (+log_children+ in this case) should be executed before the children get destroyed by the + # <tt>dependent: destroy</tt> option. # # Let's look at the code below: # @@ -222,7 +224,8 @@ module ActiveRecord # end # # In this case, the problem is that when the +before_destroy+ callback is executed, the children are not available - # because the +destroy+ callback gets executed first. You can use the +prepend+ option on the +before_destroy+ callback to avoid this. + # because the {ActiveRecord::Base#destroy}[rdoc-ref:Persistence#destroy] callback gets executed first. + # You can use the +prepend+ option on the +before_destroy+ callback to avoid this. # # class Topic < ActiveRecord::Base # has_many :children, dependent: destroy @@ -237,21 +240,21 @@ module ActiveRecord # # This way, the +before_destroy+ gets executed before the <tt>dependent: destroy</tt> is called, and the data is still available. # - # == Transactions + # == \Transactions # - # The entire callback chain of a +save+, <tt>save!</tt>, or +destroy+ call runs - # within a transaction. That includes <tt>after_*</tt> hooks. If everything - # goes fine a COMMIT is executed once the chain has been completed. + # The entire callback chain of a {#save}[rdoc-ref:Persistence#save], {#save!}[rdoc-ref:Persistence#save!], + # or {#destroy}[rdoc-ref:Persistence#destroy] call runs within a transaction. That includes <tt>after_*</tt> hooks. + # If everything goes fine a COMMIT is executed once the chain has been completed. # # If a <tt>before_*</tt> callback cancels the action a ROLLBACK is issued. You # can also trigger a ROLLBACK raising an exception in any of the callbacks, # including <tt>after_*</tt> hooks. Note, however, that in that case the client - # needs to be aware of it because an ordinary +save+ will raise such exception + # needs to be aware of it because an ordinary {#save}[rdoc-ref:Persistence#save] will raise such exception # instead of quietly returning +false+. # # == Debugging callbacks # - # The callback chain is accessible via the <tt>_*_callbacks</tt> method on an object. ActiveModel Callbacks support + # The callback chain is accessible via the <tt>_*_callbacks</tt> method on an object. Active Model \Callbacks support # <tt>:before</tt>, <tt>:after</tt> and <tt>:around</tt> as values for the <tt>kind</tt> property. The <tt>kind</tt> property # defines what part of the chain the callback runs in. # @@ -277,7 +280,7 @@ module ActiveRecord :before_destroy, :around_destroy, :after_destroy, :after_commit, :after_rollback ] - module ClassMethods + module ClassMethods # :nodoc: include ActiveModel::Callbacks end @@ -289,24 +292,28 @@ module ActiveRecord end def destroy #:nodoc: - run_callbacks(:destroy) { super } + _run_destroy_callbacks { super } + rescue RecordNotDestroyed => e + @_association_destroy_exception = e + false end def touch(*) #:nodoc: - run_callbacks(:touch) { super } + _run_touch_callbacks { super } end private + def create_or_update(*) #:nodoc: - run_callbacks(:save) { super } + _run_save_callbacks { super } end def _create_record #:nodoc: - run_callbacks(:create) { super } + _run_create_callbacks { super } end def _update_record(*) #:nodoc: - run_callbacks(:update) { super } + _run_update_callbacks { super } end end end |