Skip to content

Commit

Permalink
Add option to prepend a callback
Browse files Browse the repository at this point in the history
  • Loading branch information
A1090 committed Feb 5, 2024
1 parent de75438 commit 6c531fc
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 2 deletions.
13 changes: 11 additions & 2 deletions lib/after_commit_everywhere.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ class << self
# @param callback [#call] Callback to be executed
# @return void
def after_commit(
prepend: false,
connection: nil,
without_tx: EXECUTE,
&callback
)
register_callback(
prepend: prepend,
connection: connection,
name: __method__,
callback: callback,
Expand All @@ -64,6 +66,7 @@ def after_commit(
# @param callback [#call] Callback to be executed
# @return void
def before_commit(
prepend: false,
connection: nil,
without_tx: WARN_AND_EXECUTE,
&callback
Expand All @@ -73,6 +76,7 @@ def before_commit(
end

register_callback(
prepend: prepend,
connection: connection,
name: __method__,
callback: callback,
Expand All @@ -90,8 +94,9 @@ def before_commit(
# @param callback [#call] Callback to be executed
# @return void
# @raise [NotInTransaction] if called outside transaction.
def after_rollback(connection: nil, &callback)
def after_rollback(prepend: false, connection: nil, &callback)
register_callback(
prepend: prepend,
connection: connection,
name: __method__,
callback: callback,
Expand All @@ -100,7 +105,7 @@ def after_rollback(connection: nil, &callback)
end

# @api private
def register_callback(connection: nil, name:, without_tx:, callback:)
def register_callback(prepend:, connection: nil, name:, without_tx:, callback:)
raise ArgumentError, "Provide callback to #{name}" unless callback

unless in_transaction?(connection)
Expand All @@ -120,6 +125,10 @@ def register_callback(connection: nil, name:, without_tx:, callback:)
connection ||= default_connection
wrap = Wrap.new(connection: connection, "#{name}": callback)
connection.add_transaction_record(wrap)
if prepend
records = connection.current_transaction.instance_variable_get(:@records)
records.unshift(records.pop)
end
end

# Helper method to determine whether we're currently in transaction or not
Expand Down
28 changes: 28 additions & 0 deletions spec/after_commit_everywhere_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,34 @@
end

context "within transaction" do
context 'when prepend is true' do
let(:handler_1) { spy("handler_1") }
let(:handler_2) { spy("handler_2") }

it 'executes prepended callback first' do
ActiveRecord::Base.transaction do
example_class.new.after_commit { handler_1.call }
example_class.new.after_commit(prepend: true) { handler_2.call }
end
expect(handler_2).to have_received(:call).ordered
expect(handler_1).to have_received(:call).ordered
end
end

context 'when prepend is not specified' do
let(:handler_1) { spy("handler_1") }
let(:handler_2) { spy("handler_2") }

it 'executes callbacks in the order they were defined' do
ActiveRecord::Base.transaction do
example_class.new.after_commit { handler_1.call }
example_class.new.after_commit { handler_2.call }
end
expect(handler_1).to have_received(:call).ordered
expect(handler_2).to have_received(:call).ordered
end
end

it "executes code only after commit" do
ActiveRecord::Base.transaction do
subject
Expand Down

0 comments on commit 6c531fc

Please sign in to comment.