Cyril Duchon-Doris
Cyril Duchon-Doris

Reputation: 13979

Rails around_action in the callback stack

I just discovered around_action callbacks. I don't really understand how those callbacks work with the rest, and especially how the call stack looks like compared to using (append_)before_action or prepend_before callbacks. Would the around action callback be good for an access control like this :

ApplicationController < ...

  around_action :access_control

  private

  def access_control
  if @authorized
    yield
  else
    # Show error page
  end
end

class AdminController < ApplicationController

  before_action :authorize_admins

  private

  def authorize_admins
    if current_user.admin?
      @authorizez = true
    end
  end

Does around_action behave like an append_before_action + prepend_after_action or prepend_before_action + append_after_action ?

Or something different ?

Upvotes: 12

Views: 11268

Answers (1)

Dharam Gollapudi
Dharam Gollapudi

Reputation: 6438

around_action are more like append_before_action + prepend_after_action.

Internally, think of it like rails has two arrays, @before_actions and @after_actions. So when you declare around_action, it pushes/appends it to the end of @before_actions and it unshift/prepends to the @after_actions.

With a quick test as follows:

class SomeController < ApplicationController
  before_action :before_action
  after_action :after_action
  around_filter :around_action

  def before_action
    $stderr.puts "From before_action"
  end

  def after_action
    $stderr.puts "From after_action"
  end

  def around_action
    begin
      $stderr.puts "From around_action before yielding"
      yield
      $stderr.puts "From around_action after yielding"
    end
  end

  def index
  end
end

I got the following in the log:

Started GET "/" for 127.0.0.1 at 2016-03-21 17:11:01 -0700
Processing by SomeController#index as HTML
From before_action
From around_action before yielding
  Rendered some/index.html.slim within layouts/index (1.5ms)
From around_action after yielding
From after_action

Upvotes: 33

Related Questions