2014-12-05 90 views
2

我正在使用多語言導軌應用程序,並且我需要針對每個區域設置不同的路線。這是很難解釋這樣對我,所以我會用一個例子:基於語言環境的Rails路線

  • EN:/ EN /定價
  • 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 

我還使用012在應用程序加載時(應用程序控制器before_action),但恰好在語言環境更改之後,/ locale保持不變的其餘部分 - 當用戶嘗試重新加載頁面時會造成問題,因爲該頁面不再存在。其他點擊也可以,使用新的區域設置URI。

我在想一個系統來查明我的當前URI是否是正確的,如果沒有,重定向它,但我認爲這是不理想的。你有什麼建議嗎?

預先感謝您。

回答

-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所提到的。我只是爲了防止某人處於重構代碼太遲的情況而發佈它。

1

我一直在使用rails-translate-routes寶石爲這一段時間現在在生產網站(Qoolife is an example you can check)。

如果您使用I18n作爲翻譯後端,它將表現得很好。如果您的項目也恰好使用gettext,請查看my fork of the gem。作爲替代,你可以看看route_translator寶石。

對於任何那些,代碼看上去非常相似:

# 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這裏討論的內容。

+0

不幸的是,這不是一個理想的解決方案,它需要一個寶石,並重新整個結構。理想情況下,當用戶點擊不同的區域時,應該調用'reload_routes!'。你能爲此提出一些破解嗎?謝謝 – kellins 2014-12-05 17:30:46

+0

我肯定會更喜歡使用經過良好測試的寶石* * hack *。我實際上很樂意考慮一個「重構」而不是「返工」......而且,每次用戶點擊一個資源時調用''reload_routes!'',好像不僅醜陋而且錯過 - 對於這種方法,它也要求你做一些「返工」。我建議你考慮寶石。 – dgilperez 2014-12-05 18:23:09

+0

另外,我剛剛意識到你假裝在路線中包含語言環境而不是子域。這應該與寶石一起開箱即用。 – dgilperez 2014-12-05 18:24:10