diff options
Diffstat (limited to 'actionpack/lib/action_dispatch/routing')
-rw-r--r-- | actionpack/lib/action_dispatch/routing/inspector.rb | 32 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/mapper.rb | 76 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/route_set.rb | 13 |
3 files changed, 74 insertions, 47 deletions
diff --git a/actionpack/lib/action_dispatch/routing/inspector.rb b/actionpack/lib/action_dispatch/routing/inspector.rb index f3a5268d2e..b806ee015b 100644 --- a/actionpack/lib/action_dispatch/routing/inspector.rb +++ b/actionpack/lib/action_dispatch/routing/inspector.rb @@ -60,12 +60,10 @@ module ActionDispatch end def format(formatter, filter = nil) - routes_to_display = filter_routes(filter) - + routes_to_display = filter_routes(normalize_filter(filter)) routes = collect_routes(routes_to_display) - if routes.none? - formatter.no_routes + formatter.no_routes(collect_routes(@routes)) return formatter.result end @@ -82,9 +80,19 @@ module ActionDispatch private + def normalize_filter(filter) + if filter.is_a?(Hash) && filter[:controller] + { controller: /#{filter[:controller].downcase.sub(/_?controller\z/, '').sub('::', '/')}/ } + elsif filter + { controller: /#{filter}/, action: /#{filter}/ } + end + end + def filter_routes(filter) if filter - @routes.select { |route| route.defaults[:controller] == filter } + @routes.select do |route| + filter.any? { |default, value| route.defaults[default] =~ value } + end else @routes end @@ -136,14 +144,18 @@ module ActionDispatch @buffer << draw_header(routes) end - def no_routes - @buffer << <<-MESSAGE.strip_heredoc + def no_routes(routes) + @buffer << + if routes.none? + <<-MESSAGE.strip_heredoc You don't have any routes defined! Please add some routes in config/routes.rb. - - For more information about routes, see the Rails guide: http://guides.rubyonrails.org/routing.html. MESSAGE + else + "No routes were found for this controller" + end + @buffer << "For more information about routes, see the Rails guide: http://guides.rubyonrails.org/routing.html." end private @@ -187,7 +199,7 @@ module ActionDispatch def header(routes) end - def no_routes + def no_routes(*) @buffer << <<-MESSAGE.strip_heredoc <p>You don't have any routes defined!</p> <ul> diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 18cd205bad..afbaa45d20 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -184,26 +184,32 @@ module ActionDispatch def build_path(ast, requirements, anchor) pattern = Journey::Path::Pattern.new(ast, requirements, JOINED_SEPARATORS, anchor) - # Get all the symbol nodes followed by literals that are not the - # dummy node. - symbols = ast.find_all { |n| - n.cat? && n.left.symbol? && n.right.cat? && n.right.left.literal? - }.map(&:left) - - # Get all the symbol nodes preceded by literals. - symbols.concat ast.find_all { |n| - n.cat? && n.left.literal? && n.right.cat? && n.right.left.symbol? - }.map { |n| n.right.left } - - symbols.each { |x| - x.regexp = /(?:#{Regexp.union(x.regexp, '-')})+/ + # Find all the symbol nodes that are adjacent to literal nodes and alter + # the regexp so that Journey will partition them into custom routes. + ast.find_all { |node| + next unless node.cat? + + if node.left.literal? && node.right.symbol? + symbol = node.right + elsif node.left.literal? && node.right.cat? && node.right.left.symbol? + symbol = node.right.left + elsif node.left.symbol? && node.right.literal? + symbol = node.left + elsif node.left.symbol? && node.right.cat? && node.right.left.literal? + symbol = node.left + else + next + end + + if symbol + symbol.regexp = /(?:#{Regexp.union(symbol.regexp, '-')})+/ + end } pattern end private :build_path - private def add_wildcard_options(options, formatted, path_ast) # Add a constraint for wildcard route to make it non-greedy and match the @@ -387,24 +393,6 @@ module ActionDispatch end module Base - # You can specify what Rails should route "/" to with the root method: - # - # root to: 'pages#main' - # - # For options, see +match+, as +root+ uses it internally. - # - # You can also pass a string which will expand - # - # root 'pages#main' - # - # You should put the root route at the top of <tt>config/routes.rb</tt>, - # because this means it will be matched first. As this is the most popular route - # of most Rails applications, this is beneficial. - def root(options = {}) - name = has_named_route?(:root) ? nil : :root - match '/', { as: name, via: :get }.merge!(options) - end - # Matches a url pattern to one or more routes. # # You should not use the +match+ method in your router @@ -1689,7 +1677,20 @@ to this: @set.add_route(mapping, ast, as, anchor) end - def root(path, options={}) + # You can specify what Rails should route "/" to with the root method: + # + # root to: 'pages#main' + # + # For options, see +match+, as +root+ uses it internally. + # + # You can also pass a string which will expand + # + # root 'pages#main' + # + # You should put the root route at the top of <tt>config/routes.rb</tt>, + # because this means it will be matched first. As this is the most popular route + # of most Rails applications, this is beneficial. + def root(path, options = {}) if path.is_a?(String) options[:to] = path elsif path.is_a?(Hash) and options.empty? @@ -1701,11 +1702,11 @@ to this: if @scope.resources? with_scope_level(:root) do path_scope(parent_resource.path) do - super(options) + match_root_route(options) end end else - super(options) + match_root_route(options) end end @@ -1900,6 +1901,11 @@ to this: ensure @scope = @scope.parent end + + def match_root_route(options) + name = has_named_route?(:root) ? nil : :root + match '/', { :as => name, :via => :get }.merge!(options) + end end # Routing Concerns allow you to declare common routes that can be reused diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 2bd2e53252..846b5fa1fc 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -281,8 +281,17 @@ module ActionDispatch helper = UrlHelper.create(route, opts, route_key, url_strategy) mod.module_eval do define_method(name) do |*args| - options = nil - options = args.pop if args.last.is_a? Hash + last = args.last + options = case last + when Hash + args.pop + when ActionController::Parameters + if last.permitted? + args.pop.to_h + else + raise ArgumentError, "Generating an URL from non sanitized request parameters is insecure!" + end + end helper.call self, args, options end end |