Rails 3.2路由:多个默认值

时间:2013-07-18 23:40:22

标签: ruby-on-rails-3.2 routing defaults

我在路线中使用了两个默认参数:

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?)

感谢您的帮助!

1 个答案:

答案 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}}参数,您可以在控制器中指定默认值。