From f149eb19d4675becee164fee2881a562cdaa0551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Thu, 7 Jan 2010 15:26:31 +0100 Subject: From now on, parameters defined in default_url_options can be absent from named routes. This allows the following setup to work: # app/controllers/application_controller.rb class ApplicationController def default_url_options(options=nil) { :locale => I18n.locale } end end # From your views and controllers: I18n.locale #=> :en users_url #=> "/en/users" users_url(:pl) #=> "/pl/users" user_url(1) #=> "/en/users/1" user_url(:pl, 1) #=> "/pl/users/1" user_url(1, :locale => :pl) #=> "/pl/users/1" If you provide all expected parameters, it still works as previously. But if any parameter is missing, it tries to assign all possible ones with the hash returned in default_url_options or the one passed straight to the named route method. Beware that default_url_options in ApplicationController is not shared with ActionMailer, so you are required to always give the locale in your email views. --- .../lib/action_dispatch/routing/route_set.rb | 72 +++++++++++++++------- 1 file changed, 51 insertions(+), 21 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 0d2ffc6d69..7752642a7b 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -74,9 +74,8 @@ module ActionDispatch @routes = {} @helpers = [] - @module ||= Module.new - @module.instance_methods.each do |selector| - @module.class_eval { remove_method selector } + @module ||= Module.new do + instance_methods.each { |selector| remove_method(selector) } end end @@ -168,25 +167,56 @@ module ActionDispatch selector = url_helper_name(name, kind) hash_access_method = hash_access_name(name, kind) - # We use module_eval to avoid leaks + # We use module_eval to avoid leaks. + # + # def users_url(*args) + # if args.empty? || Hash === args.first + # options = hash_for_users_url(args.first || {}) + # else + # options = hash_for_users_url(args.extract_options!) + # default = default_url_options(options) if self.respond_to?(:default_url_options, true) + # options = (default ||= {}).merge(options) + # + # keys = [] + # keys -= options.keys unless keys.size == args.size + # + # args = args.zip(keys).inject({}) do |h, (v, k)| + # h[k] = v + # h + # end + # + # # Tell url_for to skip default_url_options + # options[:use_defaults] = false + # options.merge!(args) + # end + # + # url_for(options) + # end @module.module_eval <<-END_EVAL, __FILE__, __LINE__ + 1 - def #{selector}(*args) # def users_url(*args) - # - opts = if args.empty? || Hash === args.first # opts = if args.empty? || Hash === args.first - args.first || {} # args.first || {} - else # else - options = args.extract_options! # options = args.extract_options! - args = args.zip(#{route.segment_keys.inspect}).inject({}) do |h, (v, k)| # args = args.zip([]).inject({}) do |h, (v, k)| - h[k] = v # h[k] = v - h # h - end # end - options.merge(args) # options.merge(args) - end # end - # - url_for(#{hash_access_method}(opts)) # url_for(hash_for_users_url(opts)) - # - end # end - protected :#{selector} # protected :users_url + def #{selector}(*args) + if args.empty? || Hash === args.first + options = #{hash_access_method}(args.first || {}) + else + options = #{hash_access_method}(args.extract_options!) + default = default_url_options(options) if self.respond_to?(:default_url_options, true) + options = (default ||= {}).merge(options) + + keys = #{route.segment_keys.inspect} + keys -= options.keys unless keys.size == args.size + + args = args.zip(keys).inject({}) do |h, (v, k)| + h[k] = v + h + end + + # Tell url_for to skip default_url_options + options[:use_defaults] = false + options.merge!(args) + end + + url_for(options) + end + protected :#{selector} END_EVAL helpers << selector end -- cgit v1.2.3