基于区域设置的Rails路由

时间:2014-12-05 16:02:30

标签: ruby-on-rails ruby-on-rails-4 routes rails-i18n

我正在使用多语言rails应用程序,我需要为每个语言环境设置不同的路由。我这样解释起来很难,所以我会举个例子:

  • zh:/ en / pricing
  • es:/ es / precios

我找到了这个答案:Rails 4 i18n, how to translate routes where subdomain is used for the locale

因此我的routes.rb看起来像这样:

scope "/:locale" do            
  get "/", to: "pages#index", as: "index"
  get "/#{I18n.t("pricing")}", :to => "pages#pricing", :as => "pricing"
end

我还在应用程序加载(应用程序控制器before_action)上使用AppName::Application.reload_routes!,但恰好在语言环境更改后,/ locale保持不变后的其余URI - 当用户尝试使用时会出现问题重新加载页面,因为它不再存在。其他点击是可以的,有新的区域设置URI。

我正在考虑一个系统,以确定我当前的URI是否正确,如果没有,将其重定向到那里,但我认为这不是最理想的。你有什么建议吗?

提前谢谢。

2 个答案:

答案 0 :(得分:2)

我已经在生产网站(rails-translate-routes)暂时使用Qoolife is an example you can check gem这个确切的目的了。

如果您使用I18n作为翻译后端,它会表现得很好。如果您的项目也恰好使用gettext,请查看my fork of the gem。作为替代方案,您可以查看route_translator gem。

使用其中任何一个,代码看起来都非常相似:

# config/routes.rb
ActionDispatch::Routing::Translator.translate_from_file('config/locales/routes.yml')

# config/locales/routes.yml
en:
  routes:
    # you can leave empty locales, for example the default one
es:
  routes:
    pricing: precios

然后,您需要使用路径约束或locale在子域中设置ApplicationController。看看this issue讨论这个问题。

答案 1 :(得分:-1)

我已经修补了这个问题的解决方案。只需在设置区域设置后在应用程序控制器中设置before_action confirm_path

def confirm_path 
  current_path = Rails.application.routes.recognize_path(request.env['PATH_INFO'])
  MyApp::Application.reload_routes!
  correct_url = url_for(controller: current_path[:controller], action: current_path[:action])  
  if correct_url != request.original_url
    redirect_to correct_url, status: 301
  end
end

我不是真的推荐这个答案,我知道它并不理想。正如@dgilperez所提到的那样使用宝石。我发布它是为了防止有人处于重构您的代码为时已晚的情况。