Ruby-on-rails – How does an around_action callback work? An explanation is needed

callbackruby-on-rails

I am terribly confused about an around_action. How do they work? Can someone please provide me with an example/explanation of how they work?

This is a quote from my Agile Web Development 4 book:

Around callbacks wrap the execution of actions. You can write an
around callback in two different styles. In the first, the callback is
a single chunk of code. That code is called before the action is executed. If the callback code invokes yield, the action is executed. When the action completes, the callback code continues executing. Thus, the code before the yield is like a before action callback and the code after the yield is the after action callback. If the callback code never invokes yield. the action is not run-this is the same as having a before action callback return false.

I sort of get it when I read this. Here is an example from the Rails Guides

class ChangesController < ApplicationController
  around_action :wrap_in_transaction, only: :show

  private

  def wrap_in_transaction
    ActiveRecord::Base.transaction do
      begin
        yield
      ensure
        raise ActiveRecord::Rollback
      end
    end
  end
end

So what is happening here? Does ActiveRecord::Base.transaction begin as the "before" part and raise ActiveRecord::Rollback as the "after" part? What is this method yielding to? Is it the show? Finally what would cause the yield method to fail causing the entire callback to fail? Would it be the rendering of the show action? I don't get it. Help please.

Best Answer

My understanding is as below:

begin
    # Do before action...
    logger.info 'I am the before action'

    # Do the action, which is passed as a block to your "around filter"
    # Note that if you were to delete this line, the action will never be called!
    yield

    # Do after action...
    logger.info 'I am the after action'
ensure
    raise ActiveRecord::Rollback
end