我在路线中使用了两个默认参数:
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'])
我希望默认添加(当然)。 locale 没有问题。 Rails正确处理。 (也许是因为globalize3 gem?)
感谢您的帮助!
答案 0 :(得分:2)
映射路由时,路由声明的默认值存储在哈希中。当您呼叫路由助手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
的默认值将始终为default_url_options
中的值。路由文件,无论您在ApplicationController
url_for
中添加了什么内容。然后将这些默认值传递给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
方法链等,并返回您的路径。
此外,使用these lines of code完全从已退回的路径中删除货币参数:
path_options
它确定'eur'
(defaults
)中的默认值相当于选择它的url_options
(duhhh?),因此会因某种原因将其删除。
所以我们学到的是路线文件中的默认值始终优先于defaults:
。
因此,我的建议是从路由范围中删除:currency
密钥,然后您的URL中始终会有一个{{1}}参数,您可以在控制器中指定默认值。