我在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类是否应该考虑请求上下文。但是你会如何解决这类问题呢?