Skip to content

Commit

Permalink
after_commit runs after transactions with non-joinable parents
Browse files Browse the repository at this point in the history
after_commit callbacks run after committing a transaction whose parent
is not `joinable?`: un-nested transactions, transactions within test
cases, and transactions in `console --sandbox`.
  • Loading branch information
brainopia committed Jan 16, 2015
1 parent 090c521 commit eb72e34
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 22 deletions.
9 changes: 9 additions & 0 deletions activerecord/CHANGELOG.md
Expand Up @@ -12,6 +12,15 @@

*Sean Griffin*

* Tests now run after_commit callbacks. You no longer have to declare
`uses_transaction ‘test name’` to test the results of an after_commit.

after_commit callbacks run after committing a transaction whose parent
is not `joinable?`: un-nested transactions, transactions within test cases,
and transactions in `console --sandbox`.

*arthurnn*, *Ravil Bayramgalin*, *Matthew Draper*

* `nil` as a value for a binary column in a query no longer logs as
"<NULL binary data>", and instead logs as just "nil".

Expand Down
Expand Up @@ -142,7 +142,6 @@ def rollback
def commit
connection.commit_db_transaction
super
commit_records
end
end

Expand All @@ -159,14 +158,22 @@ def begin_transaction(options = {})
else
SavepointTransaction.new(@connection, "active_record_#{@stack.size}", options)
end

@stack.push(transaction)
transaction
end

def commit_transaction
transaction = @stack.pop
transaction.commit
transaction.records.each { |r| current_transaction.add_record(r) }
inner_transaction = @stack.pop
inner_transaction.commit

if current_transaction.joinable?
inner_transaction.records.each do |r|
current_transaction.add_record(r)
end
else
inner_transaction.commit_records
end
end

def rollback_transaction
Expand Down
Expand Up @@ -1307,7 +1307,6 @@ def test_three_levels_of_dependence
assert_nothing_raised { topic.destroy }
end

uses_transaction :test_dependence_with_transaction_support_on_failure
def test_dependence_with_transaction_support_on_failure
firm = companies(:first_firm)
clients = firm.clients
Expand Down
21 changes: 18 additions & 3 deletions activerecord/test/cases/callbacks_test.rb
Expand Up @@ -288,7 +288,12 @@ def test_create
[ :after_save, :string ],
[ :after_save, :proc ],
[ :after_save, :object ],
[ :after_save, :block ]
[ :after_save, :block ],
[ :after_commit, :block ],
[ :after_commit, :object ],
[ :after_commit, :proc ],
[ :after_commit, :string ],
[ :after_commit, :method ]
], david.history
end

Expand Down Expand Up @@ -357,7 +362,12 @@ def test_update
[ :after_save, :string ],
[ :after_save, :proc ],
[ :after_save, :object ],
[ :after_save, :block ]
[ :after_save, :block ],
[ :after_commit, :block ],
[ :after_commit, :object ],
[ :after_commit, :proc ],
[ :after_commit, :string ],
[ :after_commit, :method ]
], david.history
end

Expand Down Expand Up @@ -408,7 +418,12 @@ def test_destroy
[ :after_destroy, :string ],
[ :after_destroy, :proc ],
[ :after_destroy, :object ],
[ :after_destroy, :block ]
[ :after_destroy, :block ],
[ :after_commit, :block ],
[ :after_commit, :object ],
[ :after_commit, :proc ],
[ :after_commit, :string ],
[ :after_commit, :method ]
], david.history
end

Expand Down
27 changes: 13 additions & 14 deletions activerecord/test/cases/transaction_callbacks_test.rb
Expand Up @@ -4,7 +4,6 @@
require 'models/topic'

class TransactionCallbacksTest < ActiveRecord::TestCase
self.use_transactional_fixtures = false
fixtures :topics, :owners, :pets

class ReplyWithCallbacks < ActiveRecord::Base
Expand Down Expand Up @@ -200,21 +199,21 @@ def test_only_call_after_rollback_on_create_after_transaction_rollsback_for_new_
end

def test_call_after_rollback_when_commit_fails
@first.class.connection.singleton_class.send(:alias_method, :real_method_commit_db_transaction, :commit_db_transaction)
begin
@first.class.connection.singleton_class.class_eval do
def commit_db_transaction; raise "boom!"; end
@first.after_commit_block { |r| r.history << :after_commit }
@first.after_rollback_block { |r| r.history << :after_rollback }

assert_raises RuntimeError do
@first.transaction do
tx = @first.class.connection.transaction_manager.current_transaction
def tx.commit
raise
end

@first.save
end

@first.after_commit_block{|r| r.history << :after_commit}
@first.after_rollback_block{|r| r.history << :after_rollback}

assert !@first.save rescue nil
assert_equal [:after_rollback], @first.history
ensure
@first.class.connection.singleton_class.send(:remove_method, :commit_db_transaction)
@first.class.connection.singleton_class.send(:alias_method, :commit_db_transaction, :real_method_commit_db_transaction)
end

assert_equal [:after_rollback], @first.history
end

def test_only_call_after_rollback_on_records_rolled_back_to_a_savepoint
Expand Down

0 comments on commit eb72e34

Please sign in to comment.