Skip to content

Commit 93f0687

Browse files
joshuay03byroot
authored andcommitted
Fix [rails#50260] Support :on option in #set_callback
1 parent 8944d80 commit 93f0687

File tree

3 files changed

+78
-0
lines changed

3 files changed

+78
-0
lines changed

activerecord/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
* Introduce `ActiveRecord::Transactions::ClassMethods#set_callback`
2+
3+
It is identical to `ActiveSupport::Callbacks::ClassMethods#set_callback`
4+
but with support for `after_commit` and `after_rollback` callback options.
5+
6+
*Joshua Young*
7+
18
* Make `ActiveRecord::Encryption::Encryptor` agnostic of the serialization format used for encrypted data.
29

310
Previously, the encryptor instance only allowed an encrypted value serialized as a `String` to be passed to the message serializer.

activerecord/lib/active_record/transactions.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,25 @@ def after_rollback(*args, &block)
266266
set_callback(:rollback, :after, *args, &block)
267267
end
268268

269+
# Similar to ActiveSupport::Callbacks::ClassMethods#set_callback, but with
270+
# support for options available on #after_commit and #after_rollback callbacks.
271+
def set_callback(name, *filter_list, &block)
272+
options = filter_list.extract_options!
273+
filter_list << options
274+
275+
if name.in?([:commit, :rollback]) && options[:on]
276+
fire_on = Array(options[:on])
277+
assert_valid_transaction_action(fire_on)
278+
options[:if] = [
279+
-> { transaction_include_any_action?(fire_on) },
280+
*options[:if]
281+
]
282+
end
283+
284+
285+
super(name, *filter_list, &block)
286+
end
287+
269288
private
270289
def prepend_option
271290
if ActiveRecord.run_after_transaction_callbacks_in_order_defined

activerecord/test/cases/transaction_callbacks_test.rb

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,3 +1029,55 @@ def with_run_commit_callbacks_on_first_saved_instances_in_transaction(value, mod
10291029
end
10301030
end
10311031
end
1032+
1033+
class SetCallbackTest < ActiveRecord::TestCase
1034+
self.use_transactional_tests = false
1035+
1036+
class TopicWithHistory < ActiveRecord::Base
1037+
self.table_name = :topics
1038+
self.run_commit_callbacks_on_first_saved_instances_in_transaction = true
1039+
1040+
def self.clear_history
1041+
@@history = []
1042+
end
1043+
1044+
def self.history
1045+
@@history ||= []
1046+
end
1047+
end
1048+
1049+
class TopicWithCallbacksOnUpdate < TopicWithHistory
1050+
after_commit :after_commit_on_update_1, on: :update
1051+
after_update_commit :after_commit_on_update_2
1052+
1053+
private
1054+
def after_commit_on_update_1
1055+
self.class.history << :after_commit_on_update_1
1056+
end
1057+
1058+
def after_commit_on_update_2
1059+
self.class.history << :after_commit_on_update_2
1060+
end
1061+
end
1062+
1063+
def test_set_callback_with_on
1064+
topic = TopicWithCallbacksOnUpdate.create!(title: "New topic", written_on: Date.today)
1065+
assert_empty TopicWithCallbacksOnUpdate.history
1066+
1067+
topic.update!(title: "Updated topic 1")
1068+
expected_history = [:after_commit_on_update_2, :after_commit_on_update_1]
1069+
assert_equal expected_history, TopicWithCallbacksOnUpdate.history
1070+
1071+
TopicWithCallbacksOnUpdate.skip_callback(:commit, :after, :after_commit_on_update_2)
1072+
topic.update!(title: "Updated topic 2")
1073+
expected_history << :after_commit_on_update_1
1074+
assert_equal expected_history, TopicWithCallbacksOnUpdate.history
1075+
1076+
TopicWithCallbacksOnUpdate.set_callback(:commit, :after, :after_commit_on_update_2, on: :update)
1077+
topic = TopicWithCallbacksOnUpdate.create!(title: "New topic", written_on: Date.today)
1078+
topic.update!(title: "Updated topic 3")
1079+
expected_history << :after_commit_on_update_2
1080+
expected_history << :after_commit_on_update_1
1081+
assert_equal expected_history, TopicWithCallbacksOnUpdate.history
1082+
end
1083+
end

0 commit comments

Comments
 (0)