Q:

Inline `after_commit` Callbacks in Rails

I've got a sidekiq job that needs to be run after the commit, but only in some situations and not all, in order to avoid a common race condition.
For example, the below after_commit will always fire but the code inside will only execute if the flag is true (previously set in the verify method).
class User < ActiveRecord::Base
  ...
  after_commit do |user|
    if @enqueue_some_job
      SomeJob.new(user).enqueue
      @enqueue_some_job = nil
    end
  end

  def verify
    @enqueue_some_job = ...
    ...
    save!
  end
end

The code is a bit ugly. I'd much rather be able to somehow wrap the callback inline like this:
class User < ActiveRecord::Base
  def verify
    if ...
      run_after_commit do |user|
        SomeJob.new(user).enqueue
      end
    end
    ...
    save!
  end
end

Does anything built into Rails exist to support a syntax like this (that doesn't rely on setting a temporary instance variable)? Or do any libraries exist that extend Rails to add a syntax like this?

A:

Found a solution using a via a concern. The snippet gets reused enough that it is probably a better option to abstract the instance variable and form a reusable pattern. It doesn't handle returns (not sure which are supported via after_commit since no transaction is present to roll back.
app/models/concerns/callbackable.rb
module Callbackable
  extend ActiveSupport::Concern

  included do

    after_commit do |resource|
      if @_execute_after_commit
        @_execute_after_commit.each do |callback|
          callback.call(resource)
        end
        @_execute_after_commit = nil
      end
    end
  end

  def execute_after_commit(&callback)
    if callback
      @_execute_after_commit ||= []
      @_execute_after_commit << callback
    end
  end

end

app/models/user.rb
class User < ActiveRecord::Base
  include Callbackable

  def verify
    if ...
      execute_after_commit do |user|
        SomeJob.new(user).enqueue
      end
    end
    ...
    save!
  end
end

