aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch/routing/route_set.rb
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_dispatch/routing/route_set.rb')
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb43
1 files changed, 36 insertions, 7 deletions
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index 57a73dde75..5ecad6bc04 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -1,8 +1,10 @@
-require 'rack/mount'
require 'forwardable'
require 'active_support/core_ext/object/to_query'
require 'action_dispatch/routing/deprecated_mapper'
+$: << File.expand_path('../../vendor/rack-mount-0.6.6.pre', __FILE__)
+require 'rack/mount'
+
module ActionDispatch
module Routing
class RouteSet #:nodoc:
@@ -185,9 +187,9 @@ module ActionDispatch
end
end
- attr_accessor :routes, :named_routes
+ attr_accessor :set, :routes, :named_routes
attr_accessor :disable_clear_and_finalize, :resources_path_names
- attr_accessor :default_url_options, :request_class
+ attr_accessor :default_url_options, :request_class, :valid_conditions
def self.default_resources_path_names
{ :new => 'new', :edit => 'edit' }
@@ -199,7 +201,11 @@ module ActionDispatch
self.resources_path_names = self.class.default_resources_path_names.dup
self.controller_namespaces = Set.new
self.default_url_options = {}
+
self.request_class = request_class
+ self.valid_conditions = request_class.public_instance_methods.map { |m| m.to_sym }
+ self.valid_conditions.delete(:id)
+ self.valid_conditions.push(:controller, :action)
@disable_clear_and_finalize = false
clear!
@@ -277,7 +283,7 @@ module ActionDispatch
end
def add_route(app, conditions = {}, requirements = {}, defaults = {}, name = nil, anchor = true)
- route = Route.new(app, conditions, requirements, defaults, name, anchor)
+ route = Route.new(self, app, conditions, requirements, defaults, name, anchor)
@set.add_route(*route)
named_routes[name] = route if name
routes << route
@@ -296,6 +302,7 @@ module ActionDispatch
@extras = extras
normalize_options!
+ normalize_recall!
normalize_controller_action_id!
use_relative_controller!
controller.sub!(%r{^/}, '') if controller
@@ -336,6 +343,15 @@ module ActionDispatch
end
end
+ def normalize_recall!
+ # If the target route is not a standard route then remove controller and action
+ # from the options otherwise they will appear in the url parameters
+ if block_or_proc_route_target?
+ recall.delete(:controller) unless segment_keys.include?(:controller)
+ recall.delete(:action) unless segment_keys.include?(:action)
+ end
+ end
+
# This pulls :controller, :action, and :id out of the recall.
# The recall key is only used if there is no key in the options
# or if the key in the options is identical. If any of
@@ -371,7 +387,7 @@ module ActionDispatch
def generate
error = ActionController::RoutingError.new("No route matches #{options.inspect}")
- path, params = @set.generate(:path_info, named_route, options, recall, opts)
+ path, params = @set.set.generate(:path_info, named_route, options, recall, opts)
raise error unless path
@@ -402,6 +418,19 @@ module ActionDispatch
return false unless current_controller
controller.to_param != current_controller.to_param
end
+
+ private
+ def named_route_exists?
+ named_route && set.named_routes[named_route]
+ end
+
+ def block_or_proc_route_target?
+ named_route_exists? && !set.named_routes[named_route].app.is_a?(Dispatcher)
+ end
+
+ def segment_keys
+ named_route_exists? ? set.named_routes[named_route].segment_keys : []
+ end
end
# Generate the path indicated by the arguments, and return an array of
@@ -415,7 +444,7 @@ module ActionDispatch
end
def generate(options, recall = {}, extras = false)
- Generator.new(options, recall, @set, extras).generate
+ Generator.new(options, recall, self, extras).generate
end
RESERVED_OPTIONS = [:anchor, :params, :only_path, :host, :protocol, :port, :trailing_slash]
@@ -447,7 +476,7 @@ module ActionDispatch
# ROUTES TODO: This can be called directly, so script_name should probably be set in the router
rewritten_url << (options[:trailing_slash] ? path.sub(/\?|\z/) { "/" + $& } : path)
- rewritten_url << "##{Rack::Utils.escape(options[:anchor].to_param.to_s)}" if options[:anchor]
+ rewritten_url << "##{Rack::Mount::Utils.escape_uri(options[:anchor].to_param.to_s)}" if options[:anchor]
rewritten_url
end