diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index c048338d4047e531456d9acdd7ebb62b2bcd66fa..60303da9706531a26cb426c285347f00f9e81335 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -96,7 +96,24 @@ class NamedRouteCollection #:nodoc: def initialize @routes = {} @helpers = [] - @module = Module.new + @module = Module.new do + protected + def handle_positional_args(args, options, route) + inner_options = args.extract_options! + result = options.dup + + if args.any? + keys = route.segment_keys + if args.size < keys.size - 1 # take format into account + keys -= self.url_options.keys if self.respond_to?(:url_options) + keys -= options.keys + end + result.merge!(Hash[args.zip(keys).map { |v, k| [k, v] }]) + end + + result.merge!(inner_options) + end + end end def helper_names @@ -163,20 +180,9 @@ def define_hash_access(route, name, options) selector = hash_access_name(name, options[:only_path]) @module.module_eval do - remove_possible_method selector - - define_method(selector) do |*args| - inner_options = args.extract_options! - result = options.dup - - if args.any? - result[:_positional_args] = args - result[:_positional_keys] = route.segment_keys - end - - result.merge(inner_options) + redefine_method(selector) do |*args| + self.handle_positional_args(args, options, route) end - protected selector end helpers << selector @@ -617,8 +623,6 @@ def _generate_prefix(options = {}) def url_for(options) options = default_url_options.merge(options || {}) - handle_positional_args(options) - user, password = extract_authentication(options) path_segments = options.delete(:_path_segments) script_name = options.delete(:script_name).presence || _generate_prefix(options) @@ -688,16 +692,6 @@ def extract_authentication(options) end end - def handle_positional_args(options) - return unless args = options.delete(:_positional_args) - - keys = options.delete(:_positional_keys) - keys -= options.keys if args.size < keys.size - 1 # take format into account - - # Tell url_for to skip default_url_options - options.merge!(Hash[args.zip(keys).map { |v, k| [k, v] }]) - end - end end end