多语言路由 - url_for生成路径时未考虑的高级约束

时间:2014-08-08 13:24:13

标签: ruby-on-rails rails-routing

我在rails 3.2中有一个多语言网站,它有一些特定于语言的路由,映射到同一个动作。像:

对于mydomain.fr

match "/bonjour_monde" => 'foo#bar'

对于mydomain.de

match "/hallo_welt" => 'foo#bar'

为了解决这个问题,我在声明路线时使用了一个高级约束:

Application.routes.draw do
  constraints(SiteInitializer.for_country("fr")) do
    match "/bonjour_monde" => 'foo#bar'
  end
  constraints(SiteInitializer.for_country("de")) do
    match "/hallo_welt" => 'foo#bar'
  end
end

SiteInitializer只是一个响应匹配的类?方法并确定请求是否适用于正确的域。这实际上只是伪代码,只是展示了我的设置。

class SiteInitializer
  def initialize(country_code)
    @country_code = country_code
  end

  def self.for_country(country_code)
    new(country_code)
  end

  def matches?(request)
    # based on the request, decide if this route should be declared
    decide_which_country_code_from_request(request) == @country_code
  end
end

这很好用。在请求mysite.fr/bonjour_monde时,应用程序正确分派,路径仅绑定到其特定域。

mysite.fr/bonjour_monde => HTTP 200
mysite.fr/hallo_welt => HTTP 404
mysite.de/bonjour_monde => HTTP 404
mysite.de/hallo_welt => HTTP 200

现在,除非你开始使用url_for(:controller =>'foo',:action =>'bar')之类的东西,否则一切都很好。如果这样做,则不考虑约束。这导致从rails(Journey类)生成的路径将是任意的。

如果我在任何视图的某个地方使用url_for,比如

url_for(:controller => 'foo', :action => 'bar')

rails将选择任何与控制器操作匹配的任意声明路由,可能是声明的第一个路径,跳过以检查任何高级约束。

如果用户访问mysite.de/hallo_welt,视图会执行以下操作:

= url_for(:controller => 'foo', :action => 'bar', :page => '2')

输出可能是

mysite.de/bonjour_monde?page=2
               ^
          wrong language

实际上,我没有在代码中特别使用url_for,但是像kaminari(paginator)这样的宝石会这样做,这就是为什么在生成路径时使用标准辅助方法的库可能会受到限制。

现在,我不太确定Journey类是否应该考虑请求上下文。但是你会如何解决这类问题呢?

0 个答案:

没有答案