aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG.md4
-rw-r--r--activerecord/lib/active_record/transactions.rb2
-rw-r--r--activerecord/test/cases/transaction_callbacks_test.rb20
3 files changed, 25 insertions, 1 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 36a3d59784..dda7d19915 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,7 @@
+* Fix logic on disabling commit callbacks so they are not called unexpectedly when errors occur.
+
+ *Brian Durand*
+
* Ensure `Associations::CollectionAssociation#size` and `Associations::CollectionAssociation#empty?`
use loaded association ids if present.
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index 97cba5d1c7..be4f41050e 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -340,7 +340,7 @@ module ActiveRecord
# Ensure that it is not called if the object was never persisted (failed create),
# but call it after the commit of a destroyed object.
def committed!(should_run_callbacks: true) #:nodoc:
- if should_run_callbacks && destroyed? || persisted?
+ if should_run_callbacks && (destroyed? || persisted?)
_run_commit_without_transaction_enrollment_callbacks
_run_commit_callbacks
end
diff --git a/activerecord/test/cases/transaction_callbacks_test.rb b/activerecord/test/cases/transaction_callbacks_test.rb
index e89ac53732..05941c75ac 100644
--- a/activerecord/test/cases/transaction_callbacks_test.rb
+++ b/activerecord/test/cases/transaction_callbacks_test.rb
@@ -367,6 +367,26 @@ class TransactionCallbacksTest < ActiveRecord::TestCase
assert_match(/:on conditions for after_commit and after_rollback callbacks have to be one of \[:create, :destroy, :update\]/, e.message)
end
+ def test_after_commit_chain_not_called_on_errors
+ record_1 = TopicWithCallbacks.create!
+ record_2 = TopicWithCallbacks.create!
+ record_3 = TopicWithCallbacks.create!
+ callbacks = []
+ record_1.after_commit_block { raise }
+ record_2.after_commit_block { callbacks << record_2.id }
+ record_3.after_commit_block { callbacks << record_3.id }
+ begin
+ TopicWithCallbacks.transaction do
+ record_1.save!
+ record_2.save!
+ record_3.save!
+ end
+ rescue
+ # From record_1.after_commit
+ end
+ assert_equal [], callbacks
+ end
+
def test_saving_a_record_with_a_belongs_to_that_specifies_touching_the_parent_should_call_callbacks_on_the_parent_object
pet = Pet.first
owner = pet.owner