我对设置 Devise 了解不多,但我确实花了一些时间研究国际化 Rails 路由,所以希望这个答案对你有用,如果不是作为你问题的答案,那么作为一个接近答案的参考(内容主要是我在 i18n Railscast 的评论中写的评论的重新散列,这也是 Rails i18n 路由信息的良好来源):
您的application_controller.rb对我来说看起来不错,但也许尝试将您的routes.rb更改为如下所示:
config/routes.rb(示例)
MyApp::Application.routes.draw do
scope ":locale", locale: /#{I18n.available_locales.join("|")}/ do
# ...
match '/about', to: 'static_pages#about'
# handles /valid-locale
root to: 'static_pages#home', as: "locale_root"
# handles /valid-locale/fake-path
match '*path', to: redirect { |params, request| "/#{params[:locale]}" }
end
# handles /
root to: redirect("/#{I18n.default_locale}")
# handles /bad-locale|anything/valid-path
match '/*locale/*path', to: redirect("/#{I18n.default_locale}/%{path}")
# handles /anything|valid-path-but-no-locale
match '/*path', to: redirect("/#{I18n.default_locale}/%{path}")
end
由于有两个root_paths
,我在:locale
范围内重命名了一个,这样应用程序和测试就不会发生冲突。我使用 RSpec 测试了路由,如下所示:
规范/路由/routing_spec.rb
require 'spec_helper'
describe "Routes" do
describe "locale scoped paths" do
I18n.available_locales.each do |locale|
describe "routing" do
it "should route /:locale to the root path" do
get("/#{locale.to_s}").
should route_to("static_pages#home", locale: locale.to_s)
end
end
describe "redirecting", type: :request do
subject { response }
context "fake paths" do
let(:fake_path) { "fake_path" }
before { get "/#{locale.to_s}/#{fake_path}" }
it { should redirect_to(locale_root_path(locale)) }
end
end
end
end
describe "non-locale scoped paths" do
describe "redirecting", type: :request do
subject { response }
context "no path given" do
before { get "/" }
it { should redirect_to(locale_root_path(I18n.default_locale)) }
end
context "a valid action" do
let(:action) { "about" }
let!(:default_locale_action_path) { about_path(I18n.default_locale) }
context "with a valid but unsupported locale" do
let(:unsupported_locale) { "fr" }
before { get "/#{unsupported_locale}/#{action}" }
it { should redirect_to(default_locale_action_path) }
end
context "with invalid information for the locale" do
let(:invalid_locale) { "invalid" }
before { get "/#{invalid_locale}/#{action}" }
it { should redirect_to(default_locale_action_path) }
end
context "with no locale information" do
before { get "/#{action}" }
it { should redirect_to(default_locale_action_path) }
end
end
context "invalid information" do
let(:invalid_info) { "invalid" }
before { get "/#{invalid_info}" }
it { should redirect_to("/#{I18n.default_locale}/#{invalid_info}") }
# This will then get caught by the "redirecting fake paths" condition
# and hence be redirected to locale_root_path with I18n.default_locale
end
end
end
end