DEV Community

Tim Krins
Tim Krins

Posted on • Updated on

An experiment with controller action callback order in Rails

Here is an experiment showing how Rails action callbacks work with an instance of the ActionController::Base class, and a subclass, for my own notebook.

I am using these example controllers:

class ParentController < ActionController::Base
  before_action :_before_action_parent
  around_action :_around_action_parent
  after_action :_after_action_parent
  append_before_action :_append_before_action_parent
  append_around_action :_append_around_action_parent
  append_after_action :_append_after_action_parent
  prepend_before_action :_prepend_before_action_parent
  prepend_around_action :_prepend_around_action_parent
  prepend_after_action :_prepend_after_action_parent

  def index
    puts '    action_parent'
    head :ok
  end

  private

  def _before_action_parent
    puts '    _before_action_parent'
  end

  def _around_action_parent
    puts '    _around_action_parent-before_yield'
    yield
    puts '    _around_action_parent-after_yield'
  end

  def _after_action_parent
    puts '    _after_action_parent'
  end

  def _append_before_action_parent
    puts '    _append_before_action_parent'
  end

  def _append_around_action_parent
    puts '    _append_around_action_parent-before_yield'
    yield
    puts '    _append_around_action_parent-after_yield'
  end

  def _append_after_action_parent
    puts '    _append_after_action_parent'
  end

  def _prepend_before_action_parent
    puts '    _prepend_before_action_parent'
  end

  def _prepend_around_action_parent
    puts '    _prepend_around_action_parent-before_yield'
    yield
    puts '    _prepend_around_action_parent-after_yield'
  end

  def _prepend_after_action_parent
    puts '    _prepend_after_action_parent'
  end
end

class ChildController < ParentController
  before_action :_before_action_child
  around_action :_around_action_child
  after_action :_after_action_child
  append_before_action :_append_before_action_child
  append_around_action :_append_around_action_child
  append_after_action :_append_after_action_child
  prepend_before_action :_prepend_before_action_child
  prepend_around_action :_prepend_around_action_child
  prepend_after_action :_prepend_after_action_child

  def index
    puts 'action_child'
    head :ok
  end

  private

  def _before_action_child
    puts '_before_action_child'
  end

  def _around_action_child
    puts '_around_action_child-before_yield'
    yield
    puts '_around_action_child-after_yield'
  end

  def _after_action_child
    puts '_after_action_child'
  end

  def _append_before_action_child
    puts '_append_before_action_child'
  end

  def _append_around_action_child
    puts '_append_around_action_child-before_yield'
    yield
    puts '_append_around_action_child-after_yield'
  end

  def _append_after_action_child
    puts '_append_after_action_child'
  end

  def _prepend_before_action_child
    puts '_prepend_before_action_child'
  end

  def _prepend_around_action_child
    puts '_prepend_around_action_child-before_yield'
    yield
    puts '_prepend_around_action_child-after_yield'
  end

  def _prepend_after_action_child
    puts '_prepend_after_action_child'
  end
end
Enter fullscreen mode Exit fullscreen mode

And the console result when calling the index action of the child controller:

_prepend_around_action_child-before_yield
_prepend_before_action_child
    _prepend_around_action_parent-before_yield
    _prepend_before_action_parent
    _before_action_parent
    _around_action_parent-before_yield
    _append_before_action_parent
    _append_around_action_parent-before_yield
_before_action_child
_around_action_child-before_yield
_append_before_action_child
_append_around_action_child-before_yield
action_child
_append_after_action_child
_append_around_action_child-after_yield
_after_action_child
_around_action_child-after_yield
    _append_after_action_parent
    _append_around_action_parent-after_yield
    _after_action_parent
    _around_action_parent-after_yield
    _prepend_around_action_parent-after_yield
    _prepend_after_action_parent
_prepend_around_action_child-after_yield
_prepend_after_action_child
Enter fullscreen mode Exit fullscreen mode

Hope this helps you out!

Top comments (0)