aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Neves <arthurnn@gmail.com>2015-02-13 21:10:53 -0500
committerArthur Neves <arthurnn@gmail.com>2015-02-24 19:16:28 -0500
commit7d2a87281c7fc8ecfdf6ab7d6beedc49d166424b (patch)
tree06a27b66d511e99176c55ea40fb610bc423b1f5f
parent4a1bb9d0ce985fd105f930078a733601b29ef8a4 (diff)
downloadrails-7d2a87281c7fc8ecfdf6ab7d6beedc49d166424b.tar.gz
rails-7d2a87281c7fc8ecfdf6ab7d6beedc49d166424b.tar.bz2
rails-7d2a87281c7fc8ecfdf6ab7d6beedc49d166424b.zip
Add before_commit
[fixes #18903]
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/transaction.rb8
-rw-r--r--activerecord/lib/active_record/core.rb2
-rw-r--r--activerecord/lib/active_record/transactions.rb17
-rw-r--r--activerecord/test/cases/transaction_callbacks_test.rb5
4 files changed, 28 insertions, 4 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb b/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb
index 11440e30d4..3a1e4a4a88 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb
@@ -77,6 +77,10 @@ module ActiveRecord
@state.set_state(:committed)
end
+ def before_commit_records
+ records.uniq.each(&:before_committed!)
+ end
+
def commit_records
ite = records.uniq
while record = ite.shift
@@ -159,13 +163,15 @@ module ActiveRecord
def commit_transaction
inner_transaction = @stack.pop
- inner_transaction.commit
if current_transaction.joinable?
+ inner_transaction.commit
inner_transaction.records.each do |r|
r.add_to_transaction
end
else
+ inner_transaction.before_commit_records
+ inner_transaction.commit
inner_transaction.commit_records
end
end
diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb
index 44d587206d..a71f7a03ea 100644
--- a/activerecord/lib/active_record/core.rb
+++ b/activerecord/lib/active_record/core.rb
@@ -487,7 +487,7 @@ module ActiveRecord
end
def has_transactional_callbacks? # :nodoc:
- !_rollback_callbacks.empty? || !_commit_callbacks.empty?
+ !_rollback_callbacks.empty? || !_commit_callbacks.empty? || !_before_commit_callbacks.empty?
end
# Updates the attributes on this particular ActiveRecord object so that
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index e6580c9930..598defce50 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -7,6 +7,8 @@ module ActiveRecord
included do
define_callbacks :commit, :rollback,
+ :before_commit,
+ :before_commit_without_transaction_enrollment,
:commit_without_transaction_enrollment,
:rollback_without_transaction_enrollment,
scope: [:kind, :name]
@@ -208,6 +210,11 @@ module ActiveRecord
connection.transaction(options, &block)
end
+ def before_commit(*args, &block) # :nodoc:
+ set_options_for_callbacks!(args)
+ set_callback(:before_commit, :before, *args, &block)
+ end
+
# This callback is called after a record has been created, updated, or destroyed.
#
# You can specify that the callback should only be fired by a certain action with
@@ -235,6 +242,11 @@ module ActiveRecord
set_callback(:rollback, :after, *args, &block)
end
+ def before_commit_without_transaction_enrollment(*args, &block) # :nodoc:
+ set_options_for_callbacks!(args)
+ set_callback(:before_commit_without_transaction_enrollment, :before, *args, &block)
+ end
+
def after_commit_without_transaction_enrollment(*args, &block) # :nodoc:
set_options_for_callbacks!(args)
set_callback(:commit_without_transaction_enrollment, :after, *args, &block)
@@ -308,6 +320,11 @@ module ActiveRecord
clear_transaction_record_state
end
+ def before_committed! # :nodoc:
+ _run_before_commit_without_transaction_enrollment_callbacks
+ _run_before_commit_callbacks
+ end
+
# Call the +after_commit+ callbacks.
#
# Ensure that it is not called if the object was never persisted (failed create),
diff --git a/activerecord/test/cases/transaction_callbacks_test.rb b/activerecord/test/cases/transaction_callbacks_test.rb
index 60b0fd4112..5cac9ff84b 100644
--- a/activerecord/test/cases/transaction_callbacks_test.rb
+++ b/activerecord/test/cases/transaction_callbacks_test.rb
@@ -407,7 +407,8 @@ class TransactionEnrollmentCallbacksTest < ActiveRecord::TestCase
class TopicWithoutTransactionalEnrollmentCallbacks < ActiveRecord::Base
self.table_name = :topics
- after_commit_without_transaction_enrollment { |r| r.history << :commit }
+ before_commit_without_transaction_enrollment { |r| r.history << :before_commit }
+ after_commit_without_transaction_enrollment { |r| r.history << :after_commit }
after_rollback_without_transaction_enrollment { |r| r.history << :rollback }
def history
@@ -435,7 +436,7 @@ class TransactionEnrollmentCallbacksTest < ActiveRecord::TestCase
end
@topic.class.connection.add_transaction_record(@topic)
end
- assert_equal [:commit], @topic.history
+ assert_equal [:before_commit, :after_commit], @topic.history
end
def test_rollback_dont_enroll_transaction