, ,

Using the Rails Internationalization (I18n) API

The Ruby I18n gem provides an easy-to-use and extensible framework for providing multiple language support in your Rails application. The process of setting up the I18n gem is quite straight forward.

The gem is already shipped with Ruby on Rails (starting with Rails 2.2), and so there is no need to include that in the Gemfile. The Rails guide gives good instructions on how to set that up and works pretty well.

There is however one hiccup I encountered in using the I18n together with the Devise gem. Not sure if this is a bug or configuration issue with Devise. The issue is this: When you sign in successfully at the login page, you get directed to the home page using the last locale.

How to reproduce the issue:

When logged in, you change the language to a different one (example fr ) and then log out. At the log in page, it shows the french version. You now select another language like English. This will change the locale to en as expected and the login page will now be the English version. However after a successful login, Devise will redirect to the root page but using the previous locale, which will be fr. In this case it gets redirected to /fr.

After studying the Devise codes, and found that by default, Devise first tries to find a valid resource_return_to key in the session, then it falls back to resource_root_path, otherwise it uses the root_path, as the after_signed_in_path.

Using logger.debug, it shows that when I change the locale in the Login page, even though the locale did changed, the  session key resource_return_to continues to point to the last signed_in_root_path. Since Devise checks the resource_return_to key first, it hence redirects to that path before it will fall back on the root_path.

The way to overcome this issue is to update the resource_return_to session key each time the locale is changed in the login page. We do this in the set_locale method in the ApplicationController.

def set_locale
   I18n.locale = params[:locale] || I18n.default_locale
   session[“user_return_to”] = signed_in_root_path(User)

After this Devise will redirect to the root_path for the correct locale.

I use this little hack to resolve an issue I encountered. Not sure if this is something that only occur in my Rails App environment or in the general environment. If there is someone out there who is pulling his/her hair to try to figure out the same problem, hopefully this will help you find an answer to your question.