In my bi-lingual Rails 4 application I have a LocalesController
like this:
class LocalesController < ApplicationController
def change_loca
This is how I did it in one of Rails 4 applications:
in config/routes.rb:
Rails.application.routes.draw do
scope "(:locale)", locale: /#{I18n.available_locales.join("|")}/ do
# rest of your routes here
# for example:
resources :projects
end
end
make sure in config/environments/production.rb this line is uncommented:
config.i18n.fallbacks = true
If you wish to have a default_locale
setup other than :en
, then in config/application.rb, uncomment this line:
config.i18n.default_locale = :de # and then :de will be used as default locale
Now, last part of your setup, add this method in ApplicationController
:
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_action :set_locale
private
def set_locale
I18n.locale = params[:locale] || session[:locale] || I18n.default_locale
session[:locale] = I18n.locale
end
def default_url_options(options={})
logger.debug "default_url_options is passed options: #{options.inspect}\n"
{ locale: I18n.locale }
end
end
Now, your application can be accessed as: http://localhost:3000/en/projects
, http://localhost:3000/fr/projects
, or http://localhost:3000/projects
. The last one http://localhost:3000/projects
will use :en
as its default locale(unless you make that change in application.rb).
If you want this behaviour, you are going to have to compare the URL against the session every request. One way you might do it is like this:
before_filter :check_locale
def check_locale
if session[:locale] != params[:locale] #I'm assuming this exists in your routes.rb
params[:set_locale] = params[:locale] #Generally bad to assign things to params but it's short for the example
change_locale
end
end
Maybe it's better to set locale in routes.rb
like this:
# config/routes.rb
scope "(:locale)", locale: /en|nl/ do
resources :books
end
You can read more here http://guides.rubyonrails.org/i18n.html#setting-the-locale-from-the-url-params
UPD. If you also save locale to the session, you also need to update it on each request. You can set it in the filter as suggested in the other answer. But I prefer to use less filters:
def locale_for_request
locale = params[:locale]
if locale && I18n.locale_available?(locale)
session[:locale] = locale
else
session[:locale] || I18n.default_locale
end
end
# then use it in the around filter: I18n.with_locale(locale_for_request)