Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AquaGeek/971765 to your computer and use it in GitHub Desktop.
Save AquaGeek/971765 to your computer and use it in GitHub Desktop.
Rails Lighthouse ticket #6310
From de1cf736b3e2a3f9b9a7a84c4edfba71ebaf4f69 Mon Sep 17 00:00:00 2001
From: Brian Durand <brian@embellishedvisions.com>
Date: Tue, 18 Jan 2011 08:58:57 -0600
Subject: [PATCH 4/4] document after transaction callbacks
---
.../active_record_validations_callbacks.textile | 39 +++++++++++++++++++-
1 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/railties/guides/source/active_record_validations_callbacks.textile b/railties/guides/source/active_record_validations_callbacks.textile
index a15571f..e8009ac 100644
--- a/railties/guides/source/active_record_validations_callbacks.textile
+++ b/railties/guides/source/active_record_validations_callbacks.textile
@@ -866,7 +866,7 @@ class User < ActiveRecord::Base
validates_presence_of :login, :email
before_create {|user| user.name = user.login.capitalize
- if user.name.blank?}
+ if user.name.blank?}
end
</ruby>
@@ -986,7 +986,7 @@ As you start registering new callbacks for your models, they will be queued for
The whole callback chain is wrapped in a transaction. If any <em>before</em> callback method returns exactly +false+ or raises an exception the execution chain gets halted and a ROLLBACK is issued; <em>after</em> 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.
+WARNING. Raising an arbitrary exception may break code that expects +save+ and friends not to fail like that. The +ActiveRecord::Rollback+ exception is used precisely to tell Active Record to rollback the transaction. That one is internally captured but not re-raised.
h3. Relational Callbacks
@@ -1158,8 +1158,43 @@ In this example, the +after_create+ method would be called whenever a +Registrat
config.active_record.observers = :mailer_observer
</ruby>
+h3. Transaction Callbacks
+
+There are two additional callbacks that are triggered by the completion of a database transaction: +after_commit+ and +after_rollback+. These callbacks are very similar to the +after_save+ callback except that they don't execute until after database changes have either been committed or rolled back. They are most useful when your active record models need to interact with external systems which are not part of the database transaction.
+
+Consider, for example, the previous example where the +PictureFile+ model needs to delete a file after a record is destroyed. If anything raises an exception after the +after_destroy+ callback is called and the transaction rolls back, the file will have been deleted and the model will be left in an inconsistent state. For example, suppose that +picture_file_2+ in the code below is not valid and the +save!+ method raises an error.
+
+<ruby>
+PictureFile.transaction do
+ picture_file_1.destroy
+ picture_file_2.save!
+end
+</ruby>
+
+By using the +after_commit+ callback we can account for this case.
+
+<ruby>
+class PictureFile < ActiveRecord::Base
+ attr_accessor :delete_file
+
+ after_destroy do |picture_file|
+ picture_file.delete_file = picture_file.filepath
+ end
+
+ after_commit do |picture_file|
+ if picture_file.delete_file && File.exist?(picture_file.delete_file)
+ File.delete(picture_file.delete_file)
+ picture_file.delete_file = nil
+ end
+ end
+end
+</ruby>
+
+The +after_commit+ and +after_rollback+ callbacks are guaranteed to be called for all models created, updated, or destroyed within a transaction block. If any exceptions are raised within one of these callbacks, they will be ignored so that they don't interfere with the other callbacks. As such, if your callback code could raise an exception, you'll need to rescue it and handle it appropriately within the callback.
+
h3. Changelog
+* January 18, 2011: Add description of transaction callbacks.
* July 20, 2010: Fixed typos and rephrased some paragraphs for clarity. "Jaime Iniesta":http://jaimeiniesta.com
* May 24, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com
* May 15, 2010: Validation Errors section updated by "Emili Parreño":http://www.eparreno.com
--
1.7.3.4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment