问题
Using locale in my rails app. I have the following routes.rb
scope ":locale", locale: /#{I18n.available_locales.join("|")}/ do
root to: 'static_pages#home'
devise_for :users, :controllers => { :registrations => :registrations }
resources :blogs do
resources :comments
end
get 'tags/:tag', to: 'blogs#index', as: :tag
resources :users
get '/users/subregion_options' => 'users#subregion_options'
resources "contacts", only: [:new, :create]
match '/crew', to: 'static_pages#crew', via: 'get'
....
end
match '*path', to: redirect("/#{I18n.locale}/%{path}"), constraints: lambda { |req| !req.path.starts_with? "/#{I18n.default_locale}/" }, via: 'get'
I would like the user accessing the page to get redirected to the locale depending on language browser settings (http header). This all works - basically. However, accessing localhost:3000/ application_controller.rb is not being called -therefore the set_locale is not being executed and that means the user ends up with the welcome rails page
How can I force the set_locale to be called?
class ApplicationController < ActionController::Base
before_filter :set_locale
def set_locale
if params[:locale].blank?
redirect_to "/#{extract_locale_from_accept_language_header}"
else
I18n.locale = params[:locale]
end
end
private
def extract_locale_from_accept_language_header
case request.env['HTTP_ACCEPT_LANGUAGE'].try(:scan, /^[a-z]{2}/).try(:first).try(:to_sym)
when 'en'
'en'
when 'de'
'de'
when 'de-at'
'de'
when 'de-ch'
'de'
else
'en'
end
end
def default_url_options(options = {})
{locale: I18n.locale}
end
回答1:
I have somehow resolved the issue (not entirely sure if that is the most elegant way), by creating a redirect to trigger set locale:
In my routes.rb I added the following outside the locale scope:
root to: 'static_pages#redirect'
Here the full version
scope ":locale", locale: /#{I18n.available_locales.join("|")}/ do
match '', to: 'static_pages#home', :as => 'home', via: 'get''
devise_for :users, :controllers => { :registrations => :registrations }
resources :blogs do
resources :comments
end
get 'tags/:tag', to: 'blogs#index', as: :tag
resources :users
get '/users/subregion_options' => 'users#subregion_options'
resources "contacts", only: [:new, :create]
match '/crew', to: 'static_pages#crew', via: 'get'
....
end
I do have only one root now. I also changed the root_to to match within the locale scope, using :as => home so I can refer to it in link_to from the views as home_path.
So when user enters the xxxx.com - he/she will end up in redirect which does the following:
class StaticPagesController < ApplicationController
def redirect
redirect_to home
end
def home
end
Since the locale is blank it will now check for locale in http header and if users preferred language does exist he/she will get directed to the right page/language. For subsequent requests (i.e.: when user clicks a link) the locale will be read out from the URL parameter.
If there's a more elegant solution to this feel free to answer - points are still up for grabs.
来源:https://stackoverflow.com/questions/23188986/application-controller-not-being-executed-when-accessing-domain-without-redirect