aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_controller
diff options
context:
space:
mode:
authorPratik Naik <pratiknaik@gmail.com>2009-08-31 22:11:50 +0100
committerPratik Naik <pratiknaik@gmail.com>2009-08-31 22:11:50 +0100
commitbae00bb1cc392e1cf408369809b9cf85468bef42 (patch)
tree17103af6eeb5de96c72beda1debce28950cc7fea /actionpack/lib/action_controller
parent93c76b2fb08668bc4b8364cc8051476e6d1d15ba (diff)
parentffd2cf167040b60c26d97c01598560c87bd4b2d3 (diff)
downloadrails-bae00bb1cc392e1cf408369809b9cf85468bef42.tar.gz
rails-bae00bb1cc392e1cf408369809b9cf85468bef42.tar.bz2
rails-bae00bb1cc392e1cf408369809b9cf85468bef42.zip
Merge commit 'mainstream/master'
Diffstat (limited to 'actionpack/lib/action_controller')
-rw-r--r--actionpack/lib/action_controller/metal.rb18
-rw-r--r--actionpack/lib/action_controller/metal/compatibility.rb18
-rw-r--r--actionpack/lib/action_controller/metal/hide_actions.rb14
-rw-r--r--actionpack/lib/action_controller/metal/http_authentication.rb20
-rw-r--r--actionpack/lib/action_controller/metal/mime_responds.rb52
-rw-r--r--actionpack/lib/action_controller/metal/rack_convenience.rb8
-rw-r--r--actionpack/lib/action_controller/metal/redirector.rb3
-rw-r--r--actionpack/lib/action_controller/metal/rendering_controller.rb48
-rw-r--r--actionpack/lib/action_controller/metal/responder.rb43
-rw-r--r--actionpack/lib/action_controller/metal/streaming.rb3
-rw-r--r--actionpack/lib/action_controller/metal/url_for.rb10
-rw-r--r--actionpack/lib/action_controller/middleware.rb38
-rw-r--r--actionpack/lib/action_controller/routing/generation/url_rewriter.rb2
-rw-r--r--actionpack/lib/action_controller/routing/resources.rb30
-rw-r--r--actionpack/lib/action_controller/routing/route_set.rb25
-rw-r--r--actionpack/lib/action_controller/testing/integration.rb3
-rw-r--r--actionpack/lib/action_controller/testing/process.rb10
-rw-r--r--actionpack/lib/action_controller/testing/test_case.rb1
18 files changed, 232 insertions, 114 deletions
diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb
index 5333ca497c..51fbba3661 100644
--- a/actionpack/lib/action_controller/metal.rb
+++ b/actionpack/lib/action_controller/metal.rb
@@ -47,7 +47,7 @@ module ActionController
# and response object available. You might wish to control the
# environment and response manually for performance reasons.
- attr_internal :status, :headers, :content_type
+ attr_internal :status, :headers, :content_type, :app, :response
def initialize(*)
@_headers = {}
@@ -75,7 +75,17 @@ module ActionController
# :api: private
def to_a
- [status, headers, response_body]
+ response ? response.to_a : [status, headers, response_body]
+ end
+
+ class ActionEndpoint
+ def initialize(controller, action)
+ @controller, @action = controller, action
+ end
+
+ def call(env)
+ controller = @controller.new.call(@action, env)
+ end
end
# Return a rack endpoint for the given action. Memoize the endpoint, so
@@ -89,9 +99,7 @@ module ActionController
# Proc:: A rack application
def self.action(name)
@actions ||= {}
- @actions[name.to_s] ||= proc do |env|
- new.call(name, env)
- end
+ @actions[name.to_s] ||= ActionEndpoint.new(self, name)
end
end
end
diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb
index f94d1c669c..22f9ab219c 100644
--- a/actionpack/lib/action_controller/metal/compatibility.rb
+++ b/actionpack/lib/action_controller/metal/compatibility.rb
@@ -16,17 +16,12 @@ module ActionController
cattr_accessor :allow_concurrency
self.allow_concurrency = false
- cattr_accessor :param_parsers
- self.param_parsers = { Mime::MULTIPART_FORM => :multipart_form,
- Mime::URL_ENCODED_FORM => :url_encoded_form,
- Mime::XML => :xml_simple,
- Mime::JSON => :json }
-
cattr_accessor :relative_url_root
self.relative_url_root = ENV['RAILS_RELATIVE_URL_ROOT']
- cattr_accessor :default_charset
- self.default_charset = "utf-8"
+ class << self
+ delegate :default_charset=, :to => "ActionDispatch::Response"
+ end
# cattr_reader :protected_instance_variables
cattr_accessor :protected_instance_variables
@@ -101,11 +96,10 @@ module ActionController
options[:template].sub!(/^\//, '')
end
- options[:text] = nil if options[:nothing] == true
+ options[:text] = nil if options.delete(:nothing) == true
+ options[:text] = " " if options.key?(:text) && options[:text].nil?
- body = super
- body = [' '] if body.blank?
- body
+ super || " "
end
def _handle_method_missing
diff --git a/actionpack/lib/action_controller/metal/hide_actions.rb b/actionpack/lib/action_controller/metal/hide_actions.rb
index af68c772b1..cdacdc40a6 100644
--- a/actionpack/lib/action_controller/metal/hide_actions.rb
+++ b/actionpack/lib/action_controller/metal/hide_actions.rb
@@ -13,7 +13,9 @@ module ActionController
# 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
+ self.class.visible_action?(action_name) do
+ !hidden_actions.include?(action_name) && super
+ end
end
module ClassMethods
@@ -25,6 +27,16 @@ module ActionController
hidden_actions.merge(args.map! {|a| a.to_s })
end
+ def inherited(klass)
+ klass.instance_variable_set("@visible_actions", {})
+ super
+ end
+
+ def visible_action?(action_name)
+ return @visible_actions[action_name] if @visible_actions.key?(action_name)
+ @visible_actions[action_name] = yield
+ end
+
# Overrides AbstractController::Base#action_methods to remove any methods
# that are listed as hidden methods.
def action_methods
diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb
index 2b62a1be85..0f35a7c040 100644
--- a/actionpack/lib/action_controller/metal/http_authentication.rb
+++ b/actionpack/lib/action_controller/metal/http_authentication.rb
@@ -115,7 +115,7 @@ module ActionController
end
def authenticate_with_http_basic(&login_procedure)
- HttpAuthentication::Basic.authenticate(self, &login_procedure)
+ HttpAuthentication::Basic.authenticate(request, &login_procedure)
end
def request_http_basic_authentication(realm = "Application")
@@ -123,9 +123,9 @@ module ActionController
end
end
- def authenticate(controller, &login_procedure)
- unless authorization(controller.request).blank?
- login_procedure.call(*user_name_and_password(controller.request))
+ def authenticate(request, &login_procedure)
+ unless authorization(request).blank?
+ login_procedure.call(*user_name_and_password(request))
end
end
@@ -150,7 +150,8 @@ module ActionController
def authentication_request(controller, realm)
controller.headers["WWW-Authenticate"] = %(Basic realm="#{realm.gsub(/"/, "")}")
- controller.__send__ :render, :text => "HTTP Basic: Access denied.\n", :status => :unauthorized
+ controller.response_body = "HTTP Basic: Access denied.\n"
+ controller.status = 401
end
end
@@ -164,7 +165,7 @@ module ActionController
# Authenticate with HTTP Digest, returns true or false
def authenticate_with_http_digest(realm = "Application", &password_procedure)
- HttpAuthentication::Digest.authenticate(self, realm, &password_procedure)
+ HttpAuthentication::Digest.authenticate(request, realm, &password_procedure)
end
# Render output including the HTTP Digest authentication header
@@ -174,8 +175,8 @@ module ActionController
end
# Returns false on a valid response, true otherwise
- def authenticate(controller, realm, &password_procedure)
- authorization(controller.request) && validate_digest_response(controller.request, realm, &password_procedure)
+ def authenticate(request, realm, &password_procedure)
+ authorization(request) && validate_digest_response(request, realm, &password_procedure)
end
def authorization(request)
@@ -243,7 +244,8 @@ module ActionController
def authentication_request(controller, realm, message = nil)
message ||= "HTTP Digest: Access denied.\n"
authentication_header(controller, realm)
- controller.__send__ :render, :text => message, :status => :unauthorized
+ controller.response_body = message
+ controller.status = 401
end
# Uses an MD5 digest based on time to generate a value to be used only once.
diff --git a/actionpack/lib/action_controller/metal/mime_responds.rb b/actionpack/lib/action_controller/metal/mime_responds.rb
index c8d042acb5..3026067868 100644
--- a/actionpack/lib/action_controller/metal/mime_responds.rb
+++ b/actionpack/lib/action_controller/metal/mime_responds.rb
@@ -179,21 +179,8 @@ module ActionController #:nodoc:
def respond_to(*mimes, &block)
raise ArgumentError, "respond_to takes either types or a block, never both" if mimes.any? && block_given?
- collector = Collector.new
- mimes = collect_mimes_from_class_level if mimes.empty?
- mimes.each { |mime| collector.send(mime) }
- block.call(collector) if block_given?
-
- if format = request.negotiate_mime(collector.order)
- self.formats = [format.to_sym]
-
- if response = collector.response_for(format)
- response.call
- else
- default_render
- end
- else
- head :not_acceptable
+ if response = retrieve_response_from_mimes(mimes, &block)
+ response.call
end
end
@@ -226,10 +213,12 @@ module ActionController #:nodoc:
# is quite simple (it just needs to respond to call), you can even give
# a proc to it.
#
- def respond_with(resource, options={}, &block)
- respond_to(&block)
- rescue ActionView::MissingTemplate
- (options.delete(:responder) || responder).call(self, resource, options)
+ def respond_with(*resources, &block)
+ if response = retrieve_response_from_mimes([], &block)
+ options = resources.extract_options!
+ options.merge!(:default_response => response)
+ (options.delete(:responder) || responder).call(self, resources, options)
+ end
end
def responder
@@ -257,11 +246,29 @@ module ActionController #:nodoc:
end
end
+ # Collects mimes and return the response for the negotiated format. Returns
+ # nil if :not_acceptable was sent to the client.
+ #
+ def retrieve_response_from_mimes(mimes, &block)
+ collector = Collector.new { default_render }
+ mimes = collect_mimes_from_class_level if mimes.empty?
+ mimes.each { |mime| collector.send(mime) }
+ block.call(collector) if block_given?
+
+ if format = request.negotiate_mime(collector.order)
+ self.formats = [format.to_sym]
+ collector.response_for(format)
+ else
+ head :not_acceptable
+ nil
+ end
+ end
+
class Collector #:nodoc:
attr_accessor :order
- def initialize
- @order, @responses = [], {}
+ def initialize(&block)
+ @order, @responses, @default_response = [], {}, block
end
def any(*args, &block)
@@ -275,13 +282,12 @@ module ActionController #:nodoc:
def custom(mime_type, &block)
mime_type = mime_type.is_a?(Mime::Type) ? mime_type : Mime::Type.lookup(mime_type.to_s)
-
@order << mime_type
@responses[mime_type] ||= block
end
def response_for(mime)
- @responses[mime] || @responses[Mime::ALL]
+ @responses[mime] || @responses[Mime::ALL] || @default_response
end
def self.generate_method_for_mime(mime)
diff --git a/actionpack/lib/action_controller/metal/rack_convenience.rb b/actionpack/lib/action_controller/metal/rack_convenience.rb
index 5fac445dab..a80569c530 100644
--- a/actionpack/lib/action_controller/metal/rack_convenience.rb
+++ b/actionpack/lib/action_controller/metal/rack_convenience.rb
@@ -5,7 +5,7 @@ module ActionController
included do
delegate :headers, :status=, :location=, :content_type=,
:status, :location, :content_type, :to => "@_response"
- attr_internal :request, :response
+ attr_internal :request
end
def call(name, env)
@@ -19,12 +19,6 @@ module ActionController
@_params ||= @_request.parameters
end
- # :api: private
- def to_a
- @_response.prepare!
- @_response.to_a
- end
-
def response_body=(body)
response.body = body if response
super
diff --git a/actionpack/lib/action_controller/metal/redirector.rb b/actionpack/lib/action_controller/metal/redirector.rb
index 20060b001f..f79fd54acd 100644
--- a/actionpack/lib/action_controller/metal/redirector.rb
+++ b/actionpack/lib/action_controller/metal/redirector.rb
@@ -8,6 +8,9 @@ module ActionController
end
module Redirector
+ extend ActiveSupport::Concern
+ include AbstractController::Logger
+
def redirect_to(url, status) #:doc:
raise AbstractController::DoubleRenderError if response_body
logger.info("Redirected to #{url}") if logger && logger.info?
diff --git a/actionpack/lib/action_controller/metal/rendering_controller.rb b/actionpack/lib/action_controller/metal/rendering_controller.rb
index 5b1be763ad..4da32ca1b3 100644
--- a/actionpack/lib/action_controller/metal/rendering_controller.rb
+++ b/actionpack/lib/action_controller/metal/rendering_controller.rb
@@ -1,20 +1,56 @@
module ActionController
+ class HashKey
+ @hash_keys = Hash.new {|h,k| h[k] = Hash.new {|h,k| h[k] = {} } }
+
+ def self.get(klass, formats, locale)
+ @hash_keys[klass][formats][locale] ||= new(klass, formats, locale)
+ end
+
+ attr_accessor :hash
+ def initialize(klass, formats, locale)
+ @formats, @locale = formats, locale
+ @hash = [formats, locale].hash
+ end
+
+ alias_method :eql?, :equal?
+
+ def inspect
+ "#<HashKey -- formats: #{@formats} locale: #{@locale}>"
+ end
+ end
+
module RenderingController
extend ActiveSupport::Concern
include AbstractController::RenderingController
+ module ClassMethods
+ def clear_template_caches!
+ ActionView::Partials::PartialRenderer::TEMPLATES.clear
+ template_cache.clear
+ super
+ end
+
+ def template_cache
+ @template_cache ||= Hash.new {|h,k| h[k] = {} }
+ end
+ end
+
def process_action(*)
self.formats = request.formats.map {|x| x.to_sym}
+
+ super
+ end
+
+ def _determine_template(*)
super
end
def render(options)
+ Thread.current[:format_locale_key] = HashKey.get(self.class, formats, I18n.locale)
+
super
- self.content_type ||= begin
- mime = options[:_template].mime_type
- formats.include?(mime && mime.to_sym) || formats.include?(:all) ? mime : Mime::Type.lookup_by_extension(formats.first)
- end.to_s
+ self.content_type ||= options[:_template].mime_type.to_s
response_body
end
@@ -34,6 +70,10 @@ module ActionController
controller_path
end
+ def with_template_cache(name)
+ self.class.template_cache[Thread.current[:format_locale_key]][name] ||= super
+ end
+
def _determine_template(options)
if options.key?(:text)
options[:_template] = ActionView::TextTemplate.new(options[:text], formats.first)
diff --git a/actionpack/lib/action_controller/metal/responder.rb b/actionpack/lib/action_controller/metal/responder.rb
index 9ed99ca623..a16ed97131 100644
--- a/actionpack/lib/action_controller/metal/responder.rb
+++ b/actionpack/lib/action_controller/metal/responder.rb
@@ -64,7 +64,7 @@ module ActionController #:nodoc:
# @project = Project.find(params[:project_id])
# @task = @project.comments.build(params[:task])
# flash[:notice] = 'Task was successfully created.' if @task.save
- # respond_with([@project, @task])
+ # respond_with(@project, @task)
# end
#
# Giving an array of resources, you ensure that the responder will redirect to
@@ -74,20 +74,21 @@ module ActionController #:nodoc:
# polymorphic urls. If a project has one manager which has many tasks, it
# should be invoked as:
#
- # respond_with([@project, :manager, @task])
+ # respond_with(@project, :manager, @task)
#
# Check polymorphic_url documentation for more examples.
#
class Responder
- attr_reader :controller, :request, :format, :resource, :resource_location, :options
+ attr_reader :controller, :request, :format, :resource, :resources, :options
- def initialize(controller, resource, options={})
+ def initialize(controller, resources, options={})
@controller = controller
@request = controller.request
@format = controller.formats.first
- @resource = resource.is_a?(Array) ? resource.last : resource
- @resource_location = options[:location] || resource
+ @resource = resources.is_a?(Array) ? resources.last : resources
+ @resources = resources
@options = options
+ @default_response = options.delete(:default_response)
end
delegate :head, :render, :redirect_to, :to => :controller
@@ -109,8 +110,10 @@ module ActionController #:nodoc:
# template.
#
def to_html
+ default_render
+ rescue ActionView::MissingTemplate
if get?
- render
+ raise
elsif has_errors?
render :action => default_action
else
@@ -118,12 +121,14 @@ module ActionController #:nodoc:
end
end
- # All others formats try to render the resource given instead. For this
- # purpose a helper called display as a shortcut to render a resource with
- # the current format.
+ # All others formats follow the procedure below. First we try to render a
+ # template, if the template is not available, we verify if the resource
+ # responds to :to_format and display it.
#
def to_format
- return render unless resourceful?
+ default_render
+ rescue ActionView::MissingTemplate
+ raise unless resourceful?
if get?
display resource
@@ -144,6 +149,20 @@ module ActionController #:nodoc:
resource.respond_to?(:"to_#{format}")
end
+ # Returns the resource location by retrieving it from the options or
+ # returning the resources array.
+ #
+ def resource_location
+ options[:location] || resources
+ end
+
+ # If a given response block was given, use it, otherwise call render on
+ # controller.
+ #
+ def default_render
+ @default_response.call
+ end
+
# display is just a shortcut to render a resource with the current format.
#
# display @user, :status => :ok
@@ -162,7 +181,7 @@ module ActionController #:nodoc:
# render :xml => @user, :status => :created
#
def display(resource, given_options={})
- render given_options.merge!(options).merge!(format => resource)
+ controller.render given_options.merge!(options).merge!(format => resource)
end
# Check if the resource has errors or not.
diff --git a/actionpack/lib/action_controller/metal/streaming.rb b/actionpack/lib/action_controller/metal/streaming.rb
index 57318e8747..4761763a26 100644
--- a/actionpack/lib/action_controller/metal/streaming.rb
+++ b/actionpack/lib/action_controller/metal/streaming.rb
@@ -145,7 +145,6 @@ module ActionController #:nodoc:
def send_data(data, options = {}) #:doc:
logger.info "Sending data #{options[:filename]}" if logger
send_file_headers! options.merge(:length => data.bytesize)
- @performed_render = false
render :status => options[:status], :text => data
end
@@ -175,6 +174,8 @@ module ActionController #:nodoc:
'Content-Transfer-Encoding' => 'binary'
)
+ response.sending_file = true
+
# Fix a problem with IE 6.0 on opening downloaded files:
# If Cache-Control: no-cache is set (which Rails does by default),
# IE removes the file it just downloaded from its cache immediately
diff --git a/actionpack/lib/action_controller/metal/url_for.rb b/actionpack/lib/action_controller/metal/url_for.rb
index 7119c14cd3..14c6523045 100644
--- a/actionpack/lib/action_controller/metal/url_for.rb
+++ b/actionpack/lib/action_controller/metal/url_for.rb
@@ -4,15 +4,6 @@ module ActionController
include RackConvenience
- def process_action(*)
- initialize_current_url
- super
- end
-
- def initialize_current_url
- @url = UrlRewriter.new(request, params.clone)
- end
-
# Overwrite to implement a number of default options that all url_for-based methods will use. The default options should come in
# the form of a hash, just like the one you would use for url_for directly. Example:
#
@@ -40,6 +31,7 @@ module ActionController
when String
options
when Hash
+ @url ||= UrlRewriter.new(request, params)
@url.rewrite(rewrite_options(options))
else
polymorphic_url(options)
diff --git a/actionpack/lib/action_controller/middleware.rb b/actionpack/lib/action_controller/middleware.rb
new file mode 100644
index 0000000000..fac0ed2645
--- /dev/null
+++ b/actionpack/lib/action_controller/middleware.rb
@@ -0,0 +1,38 @@
+module ActionController
+ class Middleware < Metal
+ class ActionMiddleware
+ def initialize(controller)
+ @controller = controller
+ end
+
+ def call(env)
+ controller = @controller.allocate
+ controller.send(:initialize)
+ controller.app = @app
+ controller._call(env)
+ end
+
+ def app=(app)
+ @app = app
+ end
+ end
+
+ def self.new(app)
+ middleware = ActionMiddleware.new(self)
+ middleware.app = app
+ middleware
+ end
+
+ def _call(env)
+ @_env = env
+ @_request = ActionDispatch::Request.new(env)
+ @_response = ActionDispatch::Response.new
+ @_response.request = @_request
+ process(:index)
+ end
+
+ def index
+ call(env)
+ end
+ end
+end \ No newline at end of file
diff --git a/actionpack/lib/action_controller/routing/generation/url_rewriter.rb b/actionpack/lib/action_controller/routing/generation/url_rewriter.rb
index 9717582b5e..52b66c9303 100644
--- a/actionpack/lib/action_controller/routing/generation/url_rewriter.rb
+++ b/actionpack/lib/action_controller/routing/generation/url_rewriter.rb
@@ -172,7 +172,7 @@ module ActionController
path = rewrite_path(options)
rewritten_url << ActionController::Base.relative_url_root.to_s unless options[:skip_relative_url_root]
rewritten_url << (options[:trailing_slash] ? path.sub(/\?|\z/) { "/" + $& } : path)
- rewritten_url << "##{options[:anchor]}" if options[:anchor]
+ rewritten_url << "##{CGI.escape(options[:anchor].to_param.to_s)}" if options[:anchor]
rewritten_url
end
diff --git a/actionpack/lib/action_controller/routing/resources.rb b/actionpack/lib/action_controller/routing/resources.rb
index 2dee0a3d87..06506435a2 100644
--- a/actionpack/lib/action_controller/routing/resources.rb
+++ b/actionpack/lib/action_controller/routing/resources.rb
@@ -320,9 +320,10 @@ module ActionController
# notes.resources :attachments
# end
#
- # * <tt>:path_names</tt> - Specify different names for the 'new' and 'edit' actions. For example:
+ # * <tt>:path_names</tt> - Specify different path names for the actions. For example:
# # new_products_path == '/productos/nuevo'
- # map.resources :products, :as => 'productos', :path_names => { :new => 'nuevo', :edit => 'editar' }
+ # # bids_product_path(1) == '/productos/1/licitacoes'
+ # map.resources :products, :as => 'productos', :member => { :bids => :get }, :path_names => { :new => 'nuevo', :bids => 'licitacoes' }
#
# You can also set default action names from an environment, like this:
# config.action_controller.resources_path_names = { :new => 'nuevo', :edit => 'editar' }
@@ -528,16 +529,16 @@ module ActionController
resource = Resource.new(entities, options)
with_options :controller => resource.controller do |map|
- map_collection_actions(map, resource)
- map_default_collection_actions(map, resource)
- map_new_actions(map, resource)
- map_member_actions(map, resource)
-
map_associations(resource, options)
if block_given?
with_options(options.slice(*INHERITABLE_OPTIONS).merge(:path_prefix => resource.nesting_path_prefix, :name_prefix => resource.nesting_name_prefix), &block)
end
+
+ map_collection_actions(map, resource)
+ map_default_collection_actions(map, resource)
+ map_new_actions(map, resource)
+ map_member_actions(map, resource)
end
end
@@ -545,16 +546,16 @@ module ActionController
resource = SingletonResource.new(entities, options)
with_options :controller => resource.controller do |map|
- map_collection_actions(map, resource)
- map_new_actions(map, resource)
- map_member_actions(map, resource)
- map_default_singleton_actions(map, resource)
-
map_associations(resource, options)
if block_given?
with_options(options.slice(*INHERITABLE_OPTIONS).merge(:path_prefix => resource.nesting_path_prefix, :name_prefix => resource.nesting_name_prefix), &block)
end
+
+ map_collection_actions(map, resource)
+ map_new_actions(map, resource)
+ map_member_actions(map, resource)
+ map_default_singleton_actions(map, resource)
end
end
@@ -589,7 +590,10 @@ module ActionController
resource.collection_methods.each do |method, actions|
actions.each do |action|
[method].flatten.each do |m|
- map_resource_routes(map, resource, action, "#{resource.path}#{resource.action_separator}#{action}", "#{action}_#{resource.name_prefix}#{resource.plural}", m)
+ action_path = resource.options[:path_names][action] if resource.options[:path_names].is_a?(Hash)
+ action_path ||= action
+
+ map_resource_routes(map, resource, action, "#{resource.path}#{resource.action_separator}#{action_path}", "#{action}_#{resource.name_prefix}#{resource.plural}", m)
end
end
end
diff --git a/actionpack/lib/action_controller/routing/route_set.rb b/actionpack/lib/action_controller/routing/route_set.rb
index 0c499f3b46..25fdbf480e 100644
--- a/actionpack/lib/action_controller/routing/route_set.rb
+++ b/actionpack/lib/action_controller/routing/route_set.rb
@@ -213,7 +213,7 @@ module ActionController
self.routes = []
self.named_routes = NamedRouteCollection.new
- clear_recognize_optimized!
+ clear!
end
# Subclasses and plugins may override this method to specify a different
@@ -223,6 +223,7 @@ module ActionController
end
def draw
+ clear!
yield Mapper.new(self)
install_helpers
end
@@ -230,8 +231,10 @@ module ActionController
def clear!
routes.clear
named_routes.clear
+
@combined_regexp = nil
@routes_by_controller = nil
+
# This will force routing/recognition_optimization.rb
# to refresh optimisations.
clear_recognize_optimized!
@@ -262,7 +265,6 @@ module ActionController
def load!
Routing.use_controllers!(nil) # Clear the controller cache so we may discover new ones
- clear!
load_routes!
end
@@ -286,10 +288,12 @@ module ActionController
configuration_files.each { |config| load(config) }
@routes_last_modified = routes_changed_at
else
- add_route ":controller/:action/:id"
+ draw do |map|
+ map.connect ":controller/:action/:id"
+ end
end
end
-
+
def routes_changed_at
routes_changed_at = nil
@@ -407,9 +411,11 @@ module ActionController
# don't use the recalled keys when determining which routes to check
routes = routes_by_controller[controller][action][options.reject {|k,v| !v}.keys.sort_by { |x| x.object_id }]
- routes.each do |route|
+ routes.each_with_index do |route, index|
results = route.__send__(method, options, merged, expire_on)
- return results if results && (!results.is_a?(Array) || results.first)
+ if results && (!results.is_a?(Array) || results.first)
+ return results
+ end
end
end
@@ -460,16 +466,13 @@ module ActionController
merged = options if expire_on[:controller]
action = merged[:action] || 'index'
- routes_by_controller[controller][action][merged.keys]
+ routes_by_controller[controller][action][merged.keys][1]
end
def routes_for_controller_and_action_and_keys(controller, action, keys)
- selected = routes.select do |route|
+ routes.select do |route|
route.matches_controller_and_action? controller, action
end
- selected.sort_by do |route|
- (keys - route.significant_keys).length
- end
end
# Subclasses and plugins may override this method to extract further attributes
diff --git a/actionpack/lib/action_controller/testing/integration.rb b/actionpack/lib/action_controller/testing/integration.rb
index 5cb0f48f82..fb82f866fe 100644
--- a/actionpack/lib/action_controller/testing/integration.rb
+++ b/actionpack/lib/action_controller/testing/integration.rb
@@ -267,7 +267,8 @@ module ActionController
"CONTENT_TYPE" => "application/x-www-form-urlencoded",
"HTTP_ACCEPT" => accept
}
- env = Rack::MockRequest.env_for(path, opts)
+
+ env = ActionDispatch::TestRequest.env_for(path, opts)
(rack_environment || {}).each do |key, value|
env[key] = value
diff --git a/actionpack/lib/action_controller/testing/process.rb b/actionpack/lib/action_controller/testing/process.rb
index d32d5562e8..a58b2de379 100644
--- a/actionpack/lib/action_controller/testing/process.rb
+++ b/actionpack/lib/action_controller/testing/process.rb
@@ -52,7 +52,7 @@ module ActionController #:nodoc:
class TestResponse < ActionDispatch::TestResponse
def recycle!
@status = 200
- @header = Rack::Utils::HeaderHash.new
+ @header = {}
@writer = lambda { |x| @body << x }
@block = nil
@length = 0
@@ -84,7 +84,7 @@ module ActionController #:nodoc:
#
# Pass a true third parameter to ensure the uploaded file is opened in binary mode (only required for Windows):
# post :change_avatar, :avatar => ActionController::TestUploadedFile.new(ActionController::TestCase.fixture_path + '/files/spongebob.png', 'image/png', :binary)
- TestUploadedFile = Rack::Utils::Multipart::UploadedFile
+ TestUploadedFile = ActionDispatch::TestRequest::Multipart::UploadedFile
module TestProcess
def self.included(base)
@@ -148,7 +148,7 @@ module ActionController #:nodoc:
def xml_http_request(request_method, action, parameters = nil, session = nil, flash = nil)
@request.env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
- @request.env['HTTP_ACCEPT'] = [Mime::JS, Mime::HTML, Mime::XML, 'text/xml', Mime::ALL].join(', ')
+ @request.env['HTTP_ACCEPT'] ||= [Mime::JS, Mime::HTML, Mime::XML, 'text/xml', Mime::ALL].join(', ')
returning __send__(request_method, action, parameters, session, flash) do
@request.env.delete 'HTTP_X_REQUESTED_WITH'
@request.env.delete 'HTTP_ACCEPT'
@@ -249,6 +249,7 @@ module ActionController #:nodoc:
temporary_routes = ActionController::Routing::RouteSet.new
ActionController::Routing.module_eval { const_set :Routes, temporary_routes }
+ ActionController::Dispatcher.router = temporary_routes
yield temporary_routes
ensure
@@ -256,6 +257,7 @@ module ActionController #:nodoc:
ActionController::Routing.module_eval { remove_const :Routes }
end
ActionController::Routing.const_set(:Routes, real_routes) if real_routes
+ ActionController::Dispatcher.router = ActionController::Routing::Routes
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_controller/testing/test_case.rb b/actionpack/lib/action_controller/testing/test_case.rb
index a11755b517..b66a4c15ff 100644
--- a/actionpack/lib/action_controller/testing/test_case.rb
+++ b/actionpack/lib/action_controller/testing/test_case.rb
@@ -179,7 +179,6 @@ module ActionController
if @controller
@controller.request = @request
@controller.params = {}
- @controller.send(:initialize_current_url)
end
end