我在路由中使用两个默认参数:
scope '(/:locale)(/:currency)', currency: /eur|usd/, locale: /de|en/, defaults: { currency: 'eur' } do ...
因为货币应该用于整个访问,所以我将区域设置和货币添加到 ApplicationController 中的 default_url_options 中:
def default_url_options options = {}
{ locale: I18n.locale, currency: params['currency'] }
end
当我生成 URL 时,即使用 url_for(),Rails 默认会忘记货币。仅当我手动添加时它才有效。例如:
root_path(currency: params['currency'])
我希望默认添加它(当然)。 区域设置没有问题。 Rails 正确处理了这个问题。 (也许是因为 globalize3 gem?)
感谢您的帮助!
最佳答案
映射路由时,路由声明中的默认值将存储在哈希中。当您调用路由助手 foo_path
时,这些默认值将作为选项哈希传递到 ActionDispatch::Routing.url_for
:
def url_for(options = nil)
case options
when nil
_routes.url_for(url_options.symbolize_keys)
when Hash
_routes.url_for(options.symbolize_keys.reverse_merge!(url_options))
when String
options
else
polymorphic_url(options)
end
end
现在,当我们收到哈希时,它reverse_merge!
与url_options
(其中声明了覆盖default_url_options
的默认值) !)。由于它是 reverse_merge!
,这意味着 options
中的值优先于 url_options
中的值,因此 currency
将始终是路由文件中设置的内容,无论您在 ApplicationController
的 default_url_options
中放入什么内容。然后,这些默认值会传递到一系列 url_for
方法等,并返回您的路径。
此外,货币参数已从返回的路径中完全删除,即 these lines of code :
def format path_options
path_options.delete_if do |key, value|
value.to_s == defaults[key].to_s && !required_parts.include?(key)
end
Visitors::Formatter.new(path_options).accept(path.spec)
end
它确定 path_options
中的默认值 ('eur'
) 等于选择它的位置的 defaults
(duhhh ?),因此它出于某种原因将其删除。
因此我们了解到,路由文件中的默认值始终优先于 url_options
。
因此,我的建议是从路由范围中删除 defaults:
键,然后您的 URL 中将始终有一个 :currency
参数,并且您可以在 Controller 中指定默认值。
关于ruby-on-rails-3.2 - Rails 3.2 路由 : multiple defaults,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17735818/