Repository: rails/rails
File: actionpack/lib/abstract_controller/callbacks.rb (Ruby)

Code before:
  # * <tt>append_around_action</tt>
  # * <tt>append_before_action</tt>
  # * <tt>around_action</tt>
  # * <tt>before_action</tt>
  # * <tt>prepend_after_action</tt>
  # * <tt>prepend_around_action</tt>
  # * <tt>prepend_before_action</tt>
  # * <tt>skip_after_action</tt>
  # * <tt>skip_around_action</tt>
  # * <tt>skip_before_action</tt>
  #
  # NOTE: Calling the same callback multiple times will overwrite previous callback definitions.
  #
  module Callbacks
    extend ActiveSupport::Concern

    # Uses ActiveSupport::Callbacks as the base functionality. For
    # more details on the whole callback system, read the documentation
    # for ActiveSupport::Callbacks.
    include ActiveSupport::Callbacks

    included do
      define_callbacks :process_action,
                       terminator: ->(controller, result_lambda) { result_lambda.call; controller.performed? },
                       skip_after_callbacks_if_terminated: true
    end

    class ActionFilter # :nodoc:
      def initialize(actions)
        @actions = Array(actions).map(&:to_s).to_set
      end

      def match?(controller)
        @actions.include?(controller.action_name)
      end

      alias after  match?
      alias before match?
      alias around match?
    end

    module ClassMethods
      # If +:only+ or +:except+ are used, convert the options into the
      # +:if+ and +:unless+ options of ActiveSupport::Callbacks.
      #
      # The basic idea is that <tt>:only => :index</tt> gets converted to
      # <tt>:if => proc {|c| c.action_name == "index" }</tt>.
      #
      # Note that <tt>:only</tt> has priority over <tt>:if</tt> in case they
      # are used together.
      #

Review comment (suggestion):
I think `raise_on_missing_callback_actions` is a clearer name. What do you think?

```suggestion
      mattr_accessor :raise_on_missing_callback_actions, default: false
```

Code after:
  # * <tt>append_around_action</tt>
  # * <tt>append_before_action</tt>
  # * <tt>around_action</tt>
  # * <tt>before_action</tt>
  # * <tt>prepend_after_action</tt>
  # * <tt>prepend_around_action</tt>
  # * <tt>prepend_before_action</tt>
  # * <tt>skip_after_action</tt>
  # * <tt>skip_around_action</tt>
  # * <tt>skip_before_action</tt>
  #
  # NOTE: Calling the same callback multiple times will overwrite previous callback definitions.
  #
  module Callbacks
    extend ActiveSupport::Concern

    # Uses ActiveSupport::Callbacks as the base functionality. For
    # more details on the whole callback system, read the documentation
    # for ActiveSupport::Callbacks.
    include ActiveSupport::Callbacks

    included do
      define_callbacks :process_action,
                       terminator: ->(controller, result_lambda) { result_lambda.call; controller.performed? },
                       skip_after_callbacks_if_terminated: true
      mattr_accessor :raise_on_missing_callback_actions, default: false
    end

    class ActionFilter # :nodoc:
      def initialize(filters, conditional_key, actions)
        @filters = filters.to_a
        @conditional_key = conditional_key
        @actions = Array(actions).map(&:to_s).to_set
      end

      def match?(controller)
        if controller.raise_on_missing_callback_actions
          missing_action = @actions.find { |action| !controller.available_action?(action) }
          if missing_action
            filter_names = @filters.length == 1 ? @filters.first.inspect : @filters.inspect
            message = "The #{missing_action} action could not be found for the #{filter_names} callback on #{controller.class.name}, but it is listed in its #{@conditional_key.inspect} option"
            raise ActionNotFound.new(message, controller, missing_action)
          end
        end

        @actions.include?(controller.action_name)
      end

      alias after  match?
      alias before match?
      alias around match?