diff options
Diffstat (limited to 'actionpack/lib/action_dispatch/routing')
4 files changed, 64 insertions, 52 deletions
diff --git a/actionpack/lib/action_dispatch/routing/inspector.rb b/actionpack/lib/action_dispatch/routing/inspector.rb index 120bc54333..71a0c5e826 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? @@ -194,9 +194,9 @@ module ActionDispatch          end          def widths(routes) -          [routes.map { |r| r[:name].length }.max, -           routes.map { |r| r[:verb].length }.max, -           routes.map { |r| r[:path].length }.max] +          [routes.map { |r| r[:name].length }.max || 0, +           routes.map { |r| r[:verb].length }.max || 0, +           routes.map { |r| r[:path].length }.max || 0]          end      end diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 846a6345cb..d5eb770cb1 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/} @@ -502,11 +507,12 @@ module ActionDispatch            raise "A rack application must be specified" unless path            options[:as]  ||= app_name(app) +          target_as       = name_for_action(options[:as], path)            options[:via] ||= :all            match(path, options.merge(:to => app, :anchor => false, :format => false)) -          define_generate_prefix(app, options[:as]) +          define_generate_prefix(app, target_as)            self          end @@ -545,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) } @@ -1404,6 +1410,7 @@ module ActionDispatch              path_without_format = _path.to_s.sub(/\(\.:format\)$/, '')              if using_match_shorthand?(path_without_format, route_options)                route_options[:to] ||= path_without_format.gsub(%r{^/}, "").sub(%r{/([^/]*)$}, '#\1') +              route_options[:to].tr!("-", "_")              end              decomposed_match(_path, route_options) @@ -1434,8 +1441,8 @@ module ActionDispatch            path = path_for_action(action, options.delete(:path))            action = action.to_s.dup -          if action =~ /^[\w\/]+$/ -            options[:action] ||= action unless action.include?("/") +          if action =~ /^[\w\-\/]+$/ +            options[:action] ||= action.tr('-', '_') unless action.include?("/")            else              action = nil            end @@ -1600,10 +1607,11 @@ module ActionDispatch            def prefix_name_for_action(as, action) #:nodoc:              if as -              as.to_s +              prefix = as              elsif !canonical_action?(action, @scope[:scope_level]) -              action.to_s +              prefix = action              end +            prefix.to_s.tr('-', '_') if prefix            end            def name_for_action(as, action) #:nodoc: 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 b8abdabca5..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 @@ -361,7 +355,7 @@ module ActionDispatch          include UrlFor        end -      # Contains all the mounted helpers accross different +      # Contains all the mounted helpers across different        # engines and the `main_app` helper for the application.        # You can include this in your classes if you want to        # access routes for other engines.  | 
