【问题标题】:Rails routes based on locale基于语言环境的 Rails 路线
【发布时间】:2015-02-03 20:41:16
【问题描述】:

我正在开发一个多语言的 Rails 应用程序,我需要为每个区域设置不同的路线。对我来说很难这样解释,所以我举个例子:

  • zh:/zh/定价
  • 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 是否正确,如果不是,则将其重定向到那里,但我认为这是次优的。你有什么建议吗?

提前谢谢你。

【问题讨论】:

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


    【解决方案1】:

    我在生产站点 (Qoolife is an example you can check) 中一直使用 rails-translate-routes 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
    

    然后您需要使用路由约束或在您的ApplicationController 中设置您的locale。看看this issue 讨论这个细节的地方。

    【讨论】:

    • 不幸的是,这不是一个理想的解决方案,它需要一个宝石并重新加工整个结构。理想情况下,reload_routes! 应该在用户单击不同的语言环境时调用。你能为此建议一些技巧吗?谢谢
    • 比起hack,我肯定更喜欢使用经过良好测试的 gem。实际上,我很乐意考虑“重构”而不是“返工”......此外,每次用户点击资源时都调用reload_routes!......好吧,这似乎不仅丑陋而且误用那个方法,也需要你做一些“返工”。我建议你考虑使用 gem。
    • 另外,我刚刚意识到您假装在路由中包含语言环境而不是子域。这应该与 gem 开箱即用。
    【解决方案2】:

    我已经为这个问题打了猴子补丁。只需在设置区域设置后在应用程序控制器中设置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 提到的那样,使用 gem 代替。我发布它以防万一有人在重构您的代码时为时已晚。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-13
      • 1970-01-01
      • 2013-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-25
      相关资源
      最近更新 更多