Skip to content

Commit 7fdcbe7

Browse files
authored
Merge pull request rails#46197 from bensheldon/double_destroy_after_commit
Don't trigger `after_commit :destroy` callback again on destroy if record previously was destroyed
2 parents 0c4d89c + e32c704 commit 7fdcbe7

File tree

3 files changed

+24
-8
lines changed

3 files changed

+24
-8
lines changed

activerecord/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
* Only trigger `after_commit :destroy` callbacks when a database row is deleted.
2+
3+
This prevents `after_commit :destroy` callbacks from being triggered again
4+
when `destroy` is called multiple times on the same record.
5+
6+
*Ben Sheldon*
7+
18
* Fix `ciphertext_for` for yet-to-be-encrypted values.
29

310
Previously, `ciphertext_for` returned the cleartext of values that had not

activerecord/lib/active_record/persistence.rb

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -676,11 +676,7 @@ def delete
676676
def destroy
677677
_raise_readonly_record_error if readonly?
678678
destroy_associations
679-
@_trigger_destroy_callback = if persisted?
680-
destroy_row > 0
681-
else
682-
true
683-
end
679+
@_trigger_destroy_callback = persisted? && destroy_row > 0
684680
@destroyed = true
685681
freeze
686682
end

activerecord/test/cases/transaction_callbacks_test.rb

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,12 +204,12 @@ def test_only_call_after_commit_on_create_after_transaction_commits_for_new_reco
204204
assert_equal [], reply.history
205205
end
206206

207-
def test_only_call_after_commit_on_destroy_after_transaction_commits_for_destroyed_new_record
207+
def test_no_after_commit_on_destroy_after_transaction_commits_for_destroyed_new_record
208208
new_record = TopicWithCallbacks.new(title: "New topic", written_on: Date.today)
209209
add_transaction_execution_blocks new_record
210210

211211
new_record.destroy
212-
assert_equal [:commit_on_destroy], new_record.history
212+
assert_equal [], new_record.history
213213
end
214214

215215
def test_save_in_after_create_commit_wont_invoke_extra_after_create_commit
@@ -674,7 +674,7 @@ class TopicWithCallbacksOnUpdate < TopicWithHistory
674674
def before_save_for_transaction; end
675675
end
676676

677-
def test_trigger_once_on_multiple_deletions
677+
def test_trigger_once_on_multiple_deletion_within_transaction
678678
TopicWithCallbacksOnDestroy.clear_history
679679
topic = TopicWithCallbacksOnDestroy.new
680680
topic.save
@@ -689,6 +689,19 @@ def test_trigger_once_on_multiple_deletions
689689
assert_equal [:commit_on_destroy], TopicWithCallbacksOnDestroy.history
690690
end
691691

692+
def test_trigger_once_on_multiple_deletions
693+
TopicWithCallbacksOnDestroy.clear_history
694+
topic = TopicWithCallbacksOnDestroy.new
695+
topic.save
696+
topic_clone = TopicWithCallbacksOnDestroy.find(topic.id)
697+
698+
topic.destroy
699+
topic.destroy
700+
topic_clone.destroy
701+
702+
assert_equal [:commit_on_destroy], TopicWithCallbacksOnDestroy.history
703+
end
704+
692705
def test_rollback_on_multiple_deletions
693706
TopicWithCallbacksOnDestroy.clear_history
694707
topic = TopicWithCallbacksOnDestroy.new

0 commit comments

Comments
 (0)