View posts for April, 2009

Rails I18n and emails

Since version 2.2, Ruby on Rails comes with an integrated support for internationalization (I18n) which makes developing multi-language websites very easy. Here’s how it works. Recently I worked on a project where I used the I18n API to provide multi-language support. The website had a user system and the user was able to change the web-site’s language in his/her profile. Basically, there was a model “User” with an attribute “language”, which was stored in the database. Every time when a user would log in on the website, the web-site’s language would change to the user’s preset language with:

I18n.locale = current_user.language

However, there was a problem with the emails, which a user automatically received from the web-site. I used a cron-job with Rails’ “script/runner” to periodically send mails from a model like this:

class Task
  def self.send_mails
    User.all( :conditions => "want_mail = 1" ).each do |user|
        UserMailer.deliver_daily_mail(user)
    end
  end
end

The mail template was translated with the Rails I18n API like this:

<%= I18n.t 'daily_mail.hello' + @user.name %>
...

The problem was only that the mails were sent out in English because the web-sites default language (I18n.default_locale) was English and there was no “I18n.locale” set in “script/runner”. The easiest solution to that problem is to set the locale somewhere in your email setup:

class UserMailer < ActionMailer::Base
  def daily_mail(user)
    I18n.locale = user.language
    @recipients  = user.email
    @from        = "The Daily Mailer <daily_mail@example.com>"
    @subject     = I18n.t 'daily_mail.subject'
    @sent_on     = Time.now
    @body[:user] = user
  end
end

Alternatively, it’s possible to set the language in the email template:

<%= I18n.t('daily_mail.hello', :locale => @user.locale) + @user.name %>
...

It’s more a logical then a technical problem, but it shows how (logically) complicated multi-language web-sites can be.

Leave a Comment