aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/lib/action_controller/abstract/base.rb7
-rw-r--r--actionpack/lib/action_controller/new_base/hide_actions.rb19
-rw-r--r--actionpack/lib/action_controller/new_base/http.rb41
-rw-r--r--actionpack/test/controller/base_test.rb11
4 files changed, 49 insertions, 29 deletions
diff --git a/actionpack/lib/action_controller/abstract/base.rb b/actionpack/lib/action_controller/abstract/base.rb
index c3daef8759..a19a236ef7 100644
--- a/actionpack/lib/action_controller/abstract/base.rb
+++ b/actionpack/lib/action_controller/abstract/base.rb
@@ -95,11 +95,6 @@ module AbstractController
end
private
- # See AbstractController::Base.action_methods
- def action_methods
- self.class.action_methods
- end
-
# Returns true if the name can be considered an action. This can
# be overridden in subclasses to modify the semantics of what
# can be considered an action.
@@ -110,7 +105,7 @@ module AbstractController
# ==== Returns
# TrueClass, FalseClass
def action_method?(name)
- action_methods.include?(name)
+ self.class.action_methods.include?(name)
end
# Call the action. Override this in a subclass to modify the
diff --git a/actionpack/lib/action_controller/new_base/hide_actions.rb b/actionpack/lib/action_controller/new_base/hide_actions.rb
index 86852a26cd..af68c772b1 100644
--- a/actionpack/lib/action_controller/new_base/hide_actions.rb
+++ b/actionpack/lib/action_controller/new_base/hide_actions.rb
@@ -8,26 +8,27 @@ module ActionController
extlib_inheritable_accessor(:hidden_actions) { Set.new }
end
- def action_methods
- self.class.action_methods
- end
-
private
+ # Overrides AbstractController::Base#action_method? to return false if the
+ # action name is in the list of hidden actions.
def action_method?(action_name)
!hidden_actions.include?(action_name) && super
end
module ClassMethods
- # Sets
+ # Sets all of the actions passed in as hidden actions.
+ #
+ # ==== Parameters
+ # *args<#to_s>:: A list of actions
def hide_action(*args)
- args.each do |arg|
- self.hidden_actions << arg.to_s
- end
+ hidden_actions.merge(args.map! {|a| a.to_s })
end
+ # Overrides AbstractController::Base#action_methods to remove any methods
+ # that are listed as hidden methods.
def action_methods
- @action_methods ||= Set.new(super.reject {|name| self.hidden_actions.include?(name.to_s)})
+ @action_methods ||= Set.new(super.reject {|name| hidden_actions.include?(name)})
end
end
end
diff --git a/actionpack/lib/action_controller/new_base/http.rb b/actionpack/lib/action_controller/new_base/http.rb
index b3a80094dd..2e73561f93 100644
--- a/actionpack/lib/action_controller/new_base/http.rb
+++ b/actionpack/lib/action_controller/new_base/http.rb
@@ -2,38 +2,48 @@ require 'action_controller/abstract'
require 'active_support/core_ext/module/delegation'
module ActionController
+ # 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).
class Http < AbstractController::Base
abstract!
# :api: public
attr_internal :params, :env
- # :api: public
+ # 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
def self.controller_name
@controller_name ||= controller_path.split("/").last
end
- # :api: public
+ # Delegates to the class' #controller_name
def controller_name
self.class.controller_name
end
- # :api: public
+ # 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
def self.controller_path
@controller_path ||= self.name.sub(/Controller$/, '').underscore
end
- # :api: public
+ # Delegates to the class' #controller_path
def controller_path
self.class.controller_path
end
- # :api: plugin
- def self.call(env)
- controller = new
- controller.call(env).to_rack
- end
-
# 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
@@ -47,7 +57,7 @@ module ActionController
super
end
- # Basic implements for content_type=, location=, and headers are
+ # Basic implementations for content_type=, location=, and headers are
# provided to reduce the dependency on the RackConvenience module
# in Renderer and Redirector.
@@ -71,6 +81,15 @@ module ActionController
[status, headers, response_body]
end
+ # 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
def self.action(name)
@actions ||= {}
@actions[name.to_s] ||= proc do |env|
diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb
index 3a4cdb81d9..03fd98a85c 100644
--- a/actionpack/test/controller/base_test.rb
+++ b/actionpack/test/controller/base_test.rb
@@ -87,11 +87,11 @@ class ControllerInstanceTests < Test::Unit::TestCase
def test_action_methods
@empty_controllers.each do |c|
hide_mocha_methods_from_controller(c)
- assert_equal Set.new, c.__send__(:action_methods), "#{c.controller_path} should be empty!"
+ assert_equal Set.new, c.class.__send__(:action_methods), "#{c.controller_path} should be empty!"
end
@non_empty_controllers.each do |c|
hide_mocha_methods_from_controller(c)
- assert_equal Set.new(%w(public_action)), c.__send__(:action_methods), "#{c.controller_path} should not be empty!"
+ assert_equal Set.new(%w(public_action)), c.class.__send__(:action_methods), "#{c.controller_path} should not be empty!"
end
end
@@ -145,7 +145,12 @@ class PerformActionTest < ActionController::TestCase
def test_method_missing_is_not_an_action_name
use_controller MethodMissingController
- assert ! @controller.__send__(:action_methods).include?('method_missing')
+
+ if defined?(ActionController::Http)
+ assert ! @controller.__send__(:action_method?, 'method_missing')
+ else
+ assert ! @controller.__send__(:action_methods).include?('method_missing')
+ end
get :method_missing
assert_response :success