An experiment with controller action callback order in Rails
Tags: rails
Published: 2022-03-04 23:16:38

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:
```ruby
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
```

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
```

Hope this helps you out!