aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@gmail.com>2010-01-07 15:26:31 +0100
committerJosé Valim <jose.valim@gmail.com>2010-01-07 15:34:14 +0100
commitf149eb19d4675becee164fee2881a562cdaa0551 (patch)
treefd72fc45c5a319ec37687e19266d06b7de509682 /actionpack/lib/action_dispatch
parentf564f947d94645dca8ff67fc5c2ad161eb2bb187 (diff)
downloadrails-f149eb19d4675becee164fee2881a562cdaa0551.tar.gz
rails-f149eb19d4675becee164fee2881a562cdaa0551.tar.bz2
rails-f149eb19d4675becee164fee2881a562cdaa0551.zip
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.
Diffstat (limited to 'actionpack/lib/action_dispatch')
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb72
1 files changed, 51 insertions, 21 deletions
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