From 4c91c442295fdea93ef1a7c44c28fcd3bf407323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Wed, 17 Aug 2016 16:09:34 -0300 Subject: Push :defaults extraction down one level Since e852daa6976cc6b6b28ad0c80a188c06e226df3c only the verb methods where extracting the defaults options. It was merged a fix for the `root` method in 31fbbb7faccba25b2e3b5e10b8fca1468579d629 but `match` was still broken since `:defaults` where not extracted. This was causing routes defined using `match` and having the `:defaults` keys to not be recognized. To fix this it was extracted a new private method with the actual content of `match` and the `:defaults` extracting was moved to `match`. --- actionpack/lib/action_dispatch/routing/mapper.rb | 120 +++++++++++------------ actionpack/test/dispatch/routing_test.rb | 18 ++++ 2 files changed, 78 insertions(+), 60 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 3f4f920a87..e9173cc264 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -716,11 +716,7 @@ module ActionDispatch def map_method(method, args, &block) options = args.extract_options! options[:via] = method - if options.key?(:defaults) - defaults(options.delete(:defaults)) { match(*args, options, &block) } - else - match(*args, options, &block) - end + match(*args, options, &block) self end end @@ -1557,7 +1553,7 @@ module ActionDispatch # match 'path' => 'controller#action', via: patch # match 'path', to: 'controller#action', via: :post # match 'path', 'otherpath', on: :member, via: :get - def match(path, *rest) + def match(path, *rest, &block) if rest.empty? && Hash === path options = path path, to = options.find { |name, _value| name.is_a?(String) } @@ -1588,55 +1584,11 @@ module ActionDispatch paths = [path] + rest end - if options[:on] && !VALID_ON_OPTIONS.include?(options[:on]) - raise ArgumentError, "Unknown scope #{on.inspect} given to :on" - end - - if @scope[:to] - options[:to] ||= @scope[:to] - end - - if @scope[:controller] && @scope[:action] - options[:to] ||= "#{@scope[:controller]}##{@scope[:action]}" - end - - controller = options.delete(:controller) || @scope[:controller] - option_path = options.delete :path - to = options.delete :to - via = Mapping.check_via Array(options.delete(:via) { - @scope[:via] - }) - formatted = options.delete(:format) { @scope[:format] } - anchor = options.delete(:anchor) { true } - options_constraints = options.delete(:constraints) || {} - - path_types = paths.group_by(&:class) - path_types.fetch(String, []).each do |_path| - route_options = options.dup - if _path && option_path - ActiveSupport::Deprecation.warn <<-eowarn -Specifying strings for both :path and the route path is deprecated. Change things like this: - - match #{_path.inspect}, :path => #{option_path.inspect} - -to this: - - match #{option_path.inspect}, :as => #{_path.inspect}, :action => #{path.inspect} - eowarn - route_options[:action] = _path - route_options[:as] = _path - _path = option_path - end - to = get_to_from_path(_path, to, route_options[:action]) - decomposed_match(_path, controller, route_options, _path, to, via, formatted, anchor, options_constraints) - end - - path_types.fetch(Symbol, []).each do |action| - route_options = options.dup - decomposed_match(action, controller, route_options, option_path, to, via, formatted, anchor, options_constraints) + if options.key?(:defaults) + defaults(options.delete(:defaults)) { map_match(paths, options, &block) } + else + map_match(paths, options, &block) end - - self end def get_to_from_path(path, to, action) @@ -1912,6 +1864,7 @@ to this: def api_only? @set.api_only? end + private def path_scope(path) @@ -1921,16 +1874,63 @@ to this: @scope = @scope.parent end + def map_match(paths, options) + if options[:on] && !VALID_ON_OPTIONS.include?(options[:on]) + raise ArgumentError, "Unknown scope #{on.inspect} given to :on" + end + + if @scope[:to] + options[:to] ||= @scope[:to] + end + + if @scope[:controller] && @scope[:action] + options[:to] ||= "#{@scope[:controller]}##{@scope[:action]}" + end + + controller = options.delete(:controller) || @scope[:controller] + option_path = options.delete :path + to = options.delete :to + via = Mapping.check_via Array(options.delete(:via) { + @scope[:via] + }) + formatted = options.delete(:format) { @scope[:format] } + anchor = options.delete(:anchor) { true } + options_constraints = options.delete(:constraints) || {} + + path_types = paths.group_by(&:class) + path_types.fetch(String, []).each do |_path| + route_options = options.dup + if _path && option_path + ActiveSupport::Deprecation.warn <<-eowarn +Specifying strings for both :path and the route path is deprecated. Change things like this: + + match #{_path.inspect}, :path => #{option_path.inspect} + +to this: + + match #{option_path.inspect}, :as => #{_path.inspect}, :action => #{_path.inspect} + eowarn + route_options[:action] = _path + route_options[:as] = _path + _path = option_path + end + to = get_to_from_path(_path, to, route_options[:action]) + decomposed_match(_path, controller, route_options, _path, to, via, formatted, anchor, options_constraints) + end + + path_types.fetch(Symbol, []).each do |action| + route_options = options.dup + decomposed_match(action, controller, route_options, option_path, to, via, formatted, anchor, options_constraints) + end + + self + end + def match_root_route(options) name = has_named_route?(:root) ? nil : :root - defaults_option = options.delete(:defaults) args = ["/", { as: name, via: :get }.merge!(options)] - if defaults_option - defaults(defaults_option) { match(*args) } - else - match(*args) - end + match(*args) end end diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index 56be08f54f..ee5c30ef0e 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -1759,6 +1759,24 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest assert_equal 1, @request.params[:page] end + def test_keyed_default_string_params_with_match + draw do + match "/", to: "pages#show", via: :get, defaults: { id: "home" } + end + + get "/" + assert_equal "home", @request.params[:id] + end + + def test_default_string_params_with_match + draw do + match "/", to: "pages#show", via: :get, id: "home" + end + + get "/" + assert_equal "home", @request.params[:id] + end + def test_keyed_default_string_params_with_root draw do root to: "pages#show", defaults: { id: "home" } -- cgit v1.2.3 From 6568cfd78c89fe70ac7304d03f8f4825fe0b7c72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Wed, 17 Aug 2016 16:15:42 -0300 Subject: Change method visibility to be private Those methods are only using inside this module and by a private method so they all should be private. --- actionpack/lib/action_dispatch/routing/mapper.rb | 114 +++++++++++------------ 1 file changed, 57 insertions(+), 57 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index e9173cc264..b3acac42fc 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -1591,63 +1591,6 @@ module ActionDispatch end end - def get_to_from_path(path, to, action) - return to if to || action - - path_without_format = path.sub(/\(\.:format\)$/, "") - if using_match_shorthand?(path_without_format) - path_without_format.gsub(%r{^/}, "").sub(%r{/([^/]*)$}, '#\1').tr("-", "_") - else - nil - end - end - - def using_match_shorthand?(path) - path =~ %r{^/?[-\w]+/[-\w/]+$} - end - - def decomposed_match(path, controller, options, _path, to, via, formatted, anchor, options_constraints) # :nodoc: - if on = options.delete(:on) - send(on) { decomposed_match(path, controller, options, _path, to, via, formatted, anchor, options_constraints) } - else - case @scope.scope_level - when :resources - nested { decomposed_match(path, controller, options, _path, to, via, formatted, anchor, options_constraints) } - when :resource - member { decomposed_match(path, controller, options, _path, to, via, formatted, anchor, options_constraints) } - else - add_route(path, controller, options, _path, to, via, formatted, anchor, options_constraints) - end - end - end - - def add_route(action, controller, options, _path, to, via, formatted, anchor, options_constraints) # :nodoc: - path = path_for_action(action, _path) - raise ArgumentError, "path is required" if path.blank? - - action = action.to_s - - default_action = options.delete(:action) || @scope[:action] - - if action =~ /^[\w\-\/]+$/ - default_action ||= action.tr("-", "_") unless action.include?("/") - else - action = nil - end - - as = if !options.fetch(:as, true) # if it's set to nil or false - options.delete(:as) - else - name_for_action(options.delete(:as), action) - end - - path = Mapping.normalize_path URI.parser.escape(path), formatted - ast = Journey::Parser.parse path - - mapping = Mapping.build(@scope, @set, ast, controller, default_action, to, via, formatted, options_constraints, anchor, options) - @set.add_route(mapping, ast, as, anchor) - end - # You can specify what Rails should route "/" to with the root method: # # root to: 'pages#main' @@ -1926,6 +1869,63 @@ to this: self end + def get_to_from_path(path, to, action) + return to if to || action + + path_without_format = path.sub(/\(\.:format\)$/, "") + if using_match_shorthand?(path_without_format) + path_without_format.gsub(%r{^/}, "").sub(%r{/([^/]*)$}, '#\1').tr("-", "_") + else + nil + end + end + + def using_match_shorthand?(path) + path =~ %r{^/?[-\w]+/[-\w/]+$} + end + + def decomposed_match(path, controller, options, _path, to, via, formatted, anchor, options_constraints) # :nodoc: + if on = options.delete(:on) + send(on) { decomposed_match(path, controller, options, _path, to, via, formatted, anchor, options_constraints) } + else + case @scope.scope_level + when :resources + nested { decomposed_match(path, controller, options, _path, to, via, formatted, anchor, options_constraints) } + when :resource + member { decomposed_match(path, controller, options, _path, to, via, formatted, anchor, options_constraints) } + else + add_route(path, controller, options, _path, to, via, formatted, anchor, options_constraints) + end + end + end + + def add_route(action, controller, options, _path, to, via, formatted, anchor, options_constraints) # :nodoc: + path = path_for_action(action, _path) + raise ArgumentError, "path is required" if path.blank? + + action = action.to_s + + default_action = options.delete(:action) || @scope[:action] + + if action =~ /^[\w\-\/]+$/ + default_action ||= action.tr("-", "_") unless action.include?("/") + else + action = nil + end + + as = if !options.fetch(:as, true) # if it's set to nil or false + options.delete(:as) + else + name_for_action(options.delete(:as), action) + end + + path = Mapping.normalize_path URI.parser.escape(path), formatted + ast = Journey::Parser.parse path + + mapping = Mapping.build(@scope, @set, ast, controller, default_action, to, via, formatted, options_constraints, anchor, options) + @set.add_route(mapping, ast, as, anchor) + end + def match_root_route(options) name = has_named_route?(:root) ? nil : :root args = ["/", { as: name, via: :get }.merge!(options)] -- cgit v1.2.3