class AbstractController::Base

different things depending on the context.
expected to provide their own render method, since rendering means
using it directly, and subclasses (like ActionController::Base) are
AbstractController::Base is a low-level API. Nobody should be
= Abstract Controller Base

def self.supports_path?

support paths, only full URLs.
may return false. An Email controller for example does not
a path. A subclass of +AbstractController::Base+
Returns true if the given controller is capable of rendering
def self.supports_path?
  true
end

def _find_action_name(action_name)

Raise +AbstractController::ActionNotFound+.
* false - No valid method name could be found.
* string - The name of the method that handles the action
==== Returns

* action_name - An action name to find a method name for
==== Parameters

See method_for_action for more information.

It checks if the action name is valid and returns false otherwise.

handle the action.
Takes an action name and returns the name of the method that will
def _find_action_name(action_name)
  _valid_action_name?(action_name) && method_for_action(action_name)
end

def _handle_action_missing(*args)

This method calls #action_missing with the current action name.
was found, #method_for_action will return "_handle_action_missing".
If the action name was not found, but a method called "action_missing"
def _handle_action_missing(*args)
  action_missing(@_action_name, *args)
end

def _valid_action_name?(action_name)

Checks if the action name is valid and returns false otherwise.
def _valid_action_name?(action_name)
  !action_name.to_s.include? File::SEPARATOR
end

def abstract!

details.
Define a controller as abstract. See internal_methods for more
def abstract!
  @abstract = true
end

def action_method?(name)

* name - The name of an action to be tested
==== Parameters

it has a method defined in the controller.
Returns true if the name can be considered an action because
def action_method?(name)
  self.class.action_methods.include?(name)
end

def action_methods

* Set - A set of all methods that should be considered actions.
==== Returns

itself.
any methods that are internal, but still exist on the class
any internal methods (see internal_methods), adding back in
includes all public instance methods on a controller, less
A list of method names that should be considered actions. This
def action_methods
  @action_methods ||= begin
    # All public instance methods of this class, including ancestors
    # except for public instance methods of Base and its ancestors.
    methods = public_instance_methods(true) - internal_methods
    # Be sure to include shadowed public instance methods of this class.
    methods.concat(public_instance_methods(false))
    methods.map!(&:to_s)
    methods.to_set
  end
end

def action_methods

Delegates to the class's ::action_methods.
def action_methods
  self.class.action_methods
end

def available_action?(action_name)

* action_name - The name of an action to be tested
==== Parameters

through other means, for example, implicit render ones.
this method considers actions that are also available
false and available_action?("foo") returns true because
Notice that action_methods.include?("foo") may return

can be dispatched, false otherwise.
Returns true if a method for the action is available and
def available_action?(action_name)
  _find_action_name(action_name)
end

def clear_action_methods!

you run action_methods, they will be recalculated.
them. ::clear_action_methods! allows you to do that, so next time
action_methods are cached and there is sometimes a need to refresh
def clear_action_methods!
  @action_methods = nil
end

def controller_path

* String
==== Returns

MyApp::MyPostsController.controller_path # => "my_app/my_posts"

end

class MyApp::MyPostsController < AbstractController::Base

Returns the full controller name, underscored, without the ending Controller.
def controller_path
  @controller_path ||= name.delete_suffix("Controller").underscore unless anonymous?
end

def controller_path

Delegates to the class's ::controller_path.
def controller_path
  self.class.controller_path
end

def eager_load! # :nodoc:

:nodoc:
def eager_load! # :nodoc:
  action_methods
  nil
end

def inherited(klass) # :nodoc:

:nodoc:
def inherited(klass) # :nodoc:
  # Define the abstract ivar on subclasses so that we don't get
  # uninitialized ivar warnings
  unless klass.instance_variable_defined?(:@abstract)
    klass.instance_variable_set(:@abstract, false)
  end
  super
end

def inspect # :nodoc:

:nodoc:
def inspect # :nodoc:
  "#<#{self.class.name}:#{'%#016x' % (object_id << 1)}>"
end

def internal_methods

(ActionController::Metal and ActionController::Base are defined as abstract)
declared on abstract classes are being removed.
a controller would normally be considered action methods, so methods
instance methods on that abstract class. Public instance methods of
abstract superclass of a controller, and gets a list of all public
A list of all internal methods for a controller. This finds the first
def internal_methods
  controller = self
  methods = []
  until controller.abstract?
    methods += controller.public_instance_methods(false)
    controller = controller.superclass
  end
  controller.public_instance_methods(true) - methods
end

def method_added(name)

Refresh the cached action_methods when a new action_method is added.
def method_added(name)
  super
  clear_action_methods!
end

def method_for_action(action_name)

* nil - No method name could be found.
* string - The name of the method that handles the action
==== Returns

* action_name - An action name to find a method name for
==== Parameters

returns +nil+, an +AbstractController::ActionNotFound+ exception will be raised.
If none of these conditions are true, and +method_for_action+

the case.
also provide a method (like +_handle_method_missing+) to handle
If you override this method to handle additional cases, you may

with a template matching the action name is considered to exist.
that should be considered an action. For instance, an HTTP controller
Subclasses may override this method to add additional conditions

method and return "_handle_action_missing" if one is found.
a name that is not an action, it will look for an #action_missing
name as it receives. By default, if #method_for_action receives
handle the action. In normal cases, this method returns the same
Takes an action name and returns the name of the method that will
def method_for_action(action_name)
  if action_method?(action_name)
    action_name
  elsif respond_to?(:action_missing, true)
    "_handle_action_missing"
  end
end

def performed?

AbstractController::Callbacks.
+process_action+ callback needs to be terminated in
Tests if a response body is set. Used to determine if the
def performed?
  response_body
end

def process(action, *args)

* self
==== Returns

AbstractController::ActionNotFound error is raised.
#method_for_action. If no method can handle the action, then an
The actual method that is called is determined by calling

Calls the action going through the entire Action Dispatch stack.
def process(action, *args)
  @_action_name = action.to_s
  unless action_name = _find_action_name(@_action_name)
    raise ActionNotFound.new("The action '#{action}' could not be found for #{self.class.name}", self, action)
  end
  @_response_body = nil
  process_action(action_name, *args)
end

def process_action(...)

which is *not* necessarily the same as the action name.
Notice that the first argument is the method to be dispatched

is the intended way to override action dispatching.
behavior around processing an action. This, and not #process,
Call the action. Override this in a subclass to modify the
def process_action(...)
  send_action(...)
end