http.rb 2.9 KB
Newer Older
J
Jeremy Kemper 已提交
1 2 3
require 'action_controller/abstract'
require 'active_support/core_ext/module/delegation'

4
module ActionController
5 6 7 8 9 10
  # ActionController::Http provides a way to get a valid Rack application from a controller.
  #
  # In AbstractController, dispatching is triggered directly by calling #process on a new controller.
  # ActionController::Http provides an #action method that returns a valid Rack application for a
  # given action. Other rack builders, such as Rack::Builder, Rack::URLMap, and the Rails router,
  # can dispatch directly to the action returned by FooController.action(:index).
11 12
  class Http < AbstractController::Base
    abstract!
J
Joshua Peek 已提交
13

14
    # :api: public
15
    attr_internal :params, :env
16

17 18 19 20 21 22
    # Returns the last part of the controller's name, underscored, without the ending
    # "Controller". For instance, MyApp::MyPostsController would return "my_posts" for
    # controller_name
    #
    # ==== Returns
    # String
23 24 25 26
    def self.controller_name
      @controller_name ||= controller_path.split("/").last
    end

27
    # Delegates to the class' #controller_name
J
Joshua Peek 已提交
28 29 30
    def controller_name
      self.class.controller_name
    end
31

32 33 34 35 36 37
    # Returns the full controller name, underscored, without the ending Controller.
    # For instance, MyApp::MyPostsController would return "my_app/my_posts" for
    # controller_name.
    #
    # ==== Returns
    # String
38 39 40
    def self.controller_path
      @controller_path ||= self.name.sub(/Controller$/, '').underscore
    end
J
Joshua Peek 已提交
41

42
    # Delegates to the class' #controller_path
J
Joshua Peek 已提交
43 44 45 46
    def controller_path
      self.class.controller_path
    end

47 48 49 50 51
    # The details below can be overridden to support a specific
    # Request and Response object. The default ActionController::Base
    # implementation includes RackConvenience, which makes a request
    # and response object available. You might wish to control the
    # environment and response manually for performance reasons.
52

53 54 55 56 57 58 59
    attr_internal :status, :headers, :content_type

    def initialize(*)
      @_headers = {}
      super
    end

60
    # Basic implementations for content_type=, location=, and headers are
61 62 63 64 65 66 67 68 69
    # provided to reduce the dependency on the RackConvenience module
    # in Renderer and Redirector.

    def content_type=(type)
      headers["Content-Type"] = type.to_s
    end

    def location=(url)
      headers["Location"] = url
70
    end
J
Joshua Peek 已提交
71

72
    # :api: private
73
    def call(name, env)
74
      @_env = env
75 76 77
      process(name)
      to_rack
    end
J
Joshua Peek 已提交
78

79 80 81 82 83
    # :api: private
    def to_rack
      [status, headers, response_body]
    end

84 85 86 87 88 89 90 91 92
    # Return a rack endpoint for the given action. Memoize the endpoint, so
    # multiple calls into MyController.action will return the same object
    # for the same action.
    #
    # ==== Parameters
    # action<#to_s>:: An action name
    #
    # ==== Returns
    # Proc:: A rack application
93 94
    def self.action(name)
      @actions ||= {}
J
Jeremy Kemper 已提交
95
      @actions[name.to_s] ||= proc do |env|
96 97
        new.call(name, env)
      end
98 99 100
    end
  end
end