diff options
Diffstat (limited to 'actionpack/lib/action_dispatch/routing')
4 files changed, 52 insertions, 43 deletions
diff --git a/actionpack/lib/action_dispatch/routing/inspector.rb b/actionpack/lib/action_dispatch/routing/inspector.rb index 120bc54333..f612e91aef 100644 --- a/actionpack/lib/action_dispatch/routing/inspector.rb +++ b/actionpack/lib/action_dispatch/routing/inspector.rb @@ -69,7 +69,7 @@ module ActionDispatch end def internal? - controller.to_s =~ %r{\Arails/(info|welcome)} || path =~ %r{\A#{Rails.application.config.assets.prefix}} + controller.to_s =~ %r{\Arails/(info|mailers|welcome)} || path =~ %r{\A#{Rails.application.config.assets.prefix}\z} end def engine? diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index bfba8d143d..18f37dc732 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -3,6 +3,7 @@ require 'active_support/core_ext/hash/reverse_merge' require 'active_support/core_ext/hash/slice' require 'active_support/core_ext/enumerable' require 'active_support/core_ext/array/extract_options' +require 'active_support/core_ext/module/remove_method' require 'active_support/inflector' require 'action_dispatch/routing/redirection' @@ -217,8 +218,12 @@ module ActionDispatch controller ||= default_controller action ||= default_action - unless controller.is_a?(Regexp) - controller = [@scope[:module], controller].compact.join("/").presence + if @scope[:module] && !controller.is_a?(Regexp) + if controller =~ %r{\A/} + controller = controller[1..-1] + else + controller = [@scope[:module], controller].compact.join("/").presence + end end if controller.is_a?(String) && controller =~ %r{\A/} @@ -546,11 +551,11 @@ module ActionDispatch _routes = @set app.routes.define_mounted_helper(name) app.routes.singleton_class.class_eval do - define_method :mounted? do + redefine_method :mounted? do true end - define_method :_generate_prefix do |options| + redefine_method :_generate_prefix do |options| prefix_options = options.slice(*_route.segment_keys) # we must actually delete prefix segment keys to avoid passing them to next url_for _route.segment_keys.each { |k| options.delete(k) } diff --git a/actionpack/lib/action_dispatch/routing/redirection.rb b/actionpack/lib/action_dispatch/routing/redirection.rb index cbf4c5aa8b..b08e62543b 100644 --- a/actionpack/lib/action_dispatch/routing/redirection.rb +++ b/actionpack/lib/action_dispatch/routing/redirection.rb @@ -26,14 +26,19 @@ module ActionDispatch end uri = URI.parse(path(req.symbolized_path_parameters, req)) + + unless uri.host + if relative_path?(uri.path) + uri.path = "#{req.script_name}/#{uri.path}" + elsif uri.path.empty? + uri.path = req.script_name.empty? ? "/" : req.script_name + end + end + uri.scheme ||= req.scheme uri.host ||= req.host uri.port ||= req.port unless req.standard_port? - if relative_path?(uri.path) - uri.path = "#{req.script_name}/#{uri.path}" - end - body = %(<html><body>You are being <a href="#{ERB::Util.h(uri.to_s)}">redirected</a>.</body></html>) headers = { @@ -112,11 +117,16 @@ module ActionDispatch url_options[:path] = (url_options[:path] % escape_path(params)) end - if relative_path?(url_options[:path]) - url_options[:path] = "/#{url_options[:path]}" - url_options[:script_name] = request.script_name + unless options[:host] || options[:domain] + if relative_path?(url_options[:path]) + url_options[:path] = "/#{url_options[:path]}" + url_options[:script_name] = request.script_name + elsif url_options[:path].empty? + url_options[:path] = request.script_name.empty? ? "/" : "" + url_options[:script_name] = request.script_name + end end - + ActionDispatch::Http::URL.url_for url_options end diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 04faabef37..a03fb4cee7 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -163,9 +163,10 @@ module ActionDispatch def initialize(route, options) super - @path_parts = @route.required_parts - @arg_size = @path_parts.size - @string_route = @route.optimized_path + @klass = Journey::Router::Utils + @required_parts = @route.required_parts + @arg_size = @required_parts.size + @optimized_path = @route.optimized_path end def call(t, args) @@ -182,43 +183,36 @@ module ActionDispatch private def optimized_helper(args) - path = @string_route.dup - klass = Journey::Router::Utils + params = Hash[parameterize_args(args)] + missing_keys = missing_keys(params) - @path_parts.zip(args) do |part, arg| - parameterized_arg = arg.to_param + unless missing_keys.empty? + raise_generation_error(params, missing_keys) + end - if parameterized_arg.nil? || parameterized_arg.empty? - raise_generation_error(args) - end + @optimized_path.map{ |segment| replace_segment(params, segment) }.join + end - # Replace each route parameter - # e.g. :id for regular parameter or *path for globbing - # with ruby string interpolation code - path.gsub!(/(\*|:)#{part}/, klass.escape_fragment(parameterized_arg)) - end - path + def replace_segment(params, segment) + Symbol === segment ? @klass.escape_fragment(params[segment]) : segment end def optimize_routes_generation?(t) t.send(:optimize_routes_generation?) end - def raise_generation_error(args) - parts, missing_keys = [], [] - - @path_parts.zip(args) do |part, arg| - parameterized_arg = arg.to_param - - if parameterized_arg.nil? || parameterized_arg.empty? - missing_keys << part - end + def parameterize_args(args) + @required_parts.zip(args.map(&:to_param)) + end - parts << [part, arg] - end + def missing_keys(args) + args.select{ |part, arg| arg.nil? || arg.empty? }.keys + end - message = "No route matches #{Hash[parts].inspect}" - message << " missing required keys: #{missing_keys.inspect}" + def raise_generation_error(args, missing_keys) + constraints = Hash[@route.requirements.merge(args).sort] + message = "No route matches #{constraints.inspect}" + message << " missing required keys: #{missing_keys.sort.inspect}" raise ActionController::UrlGenerationError, message end @@ -226,7 +220,7 @@ module ActionDispatch def initialize(route, options) @options = options - @segment_keys = route.segment_keys + @segment_keys = route.segment_keys.uniq @route = route end |