I just realized that the recommended Rails way to set locale in your controller
before_filter :set_locale
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
end
sets the locale globally. The code above works, but I wonder is default_locale
really default if you have to type it explicitly?
What I'd expect is to have a locale per request (like we have session per request) and doing something like:
def set_locale
locale = params[:locale] if params[:locale]
end
And having I18n.default_locale
used by default otherwise. This would match ideally the optional locale in path:
# config/routes.rb
scope "(:locale)", :locale => /en|nl/ do
resources :books
end
For now if for some reason I skip locale setting in some action it uses the locale set in the previous request which could be from another user!
And isn't there a potential race condition as one request can change global I18n.locale
while another request (having set another locale beforehande) is in the middle of rendering?
UPDATE: Some details I found for now, from the I18n documentstion:
Sets the current locale pseudo-globally, i.e. in the Thread.current hash def locale=(locale)
Now I want to understand if every request is a separate thread.
UPDATE 2: See my answer for explanation.