Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Execute irreversible actions only when transactions are not rolled back

branch: master

Fetching latest commit…

Octocat-spinner-32-eaf2f5

Cannot retrieve the latest commit at this time

Octocat-spinner-32 gemfiles
Octocat-spinner-32 lib
Octocat-spinner-32 spec
Octocat-spinner-32 .travis.yml
Octocat-spinner-32 Appraisals
Octocat-spinner-32 Gemfile
Octocat-spinner-32 Gemfile.lock
Octocat-spinner-32 Rakefile
Octocat-spinner-32 Readme.md
Octocat-spinner-32 ar_after_transaction.gemspec
Readme.md

Do something only after the currently open transactions have finished.

Normally everything gets rolled back when a transaction fails, but you cannot roll back sending an email or adding a job to Resque.

Install

gem install ar_after_transaction

Usage

just-in-time callbacks

class User
  after_create :do_stuff, :oops

  def do_stuff
    after_transaction do
      send_an_email # cannot be rolled back
    end
    comments.create(...) # will be rolled back
  end

  def oops
    raise "do the rolback!"
  end
end

General 'this should be rolled back when in a transaction' code like jobs

class Resque
  def revertable_enqueue(*args)
    ActiveRecord::Base.after_transaction do
      enqueue(*args)
    end
  end
end

When not in a transaction

after_transaction will perform the given block immediately

Transactional fixtures <-> normally_open_transactions

after_transaction assumes zero open transactions.
If you use transactional fixtures you should change it in test mode.

# config/environments/test.rb
config.after_initialize do
  ActiveRecord::Base.normally_open_transactions = 1
end

Rails 3: after_commit hook can replace the first usage example:

class User
  after_commit :send_an_email :on=>:create
  after_create :do_stuff, :oops
  ...
end

Alternative

Rails 3+

  • basic support is built in, use it if you can!
  • after_commit :foo
  • after_commit :bar, :on => :create / :update

after_commit

  • pro: threadsafe
  • pro: more fine-grained callbacks (before_commit, after_commit, before_rollback, after_rollback)
  • con: doesn't let you define after_transaction callbacks anywhere like ar_after_transaction does (outside of the after_commit, etc. callbacks which only happen at certain points in the model's life cycle)
  • con: more complex

Authors

Original idea and code from Jamis Buck (post by Jeremy Kemper)

Contributors

Michael Grosser
michael@grosser.it
License: MIT
Build Status

Something went wrong with that request. Please try again.