Search code examples
ruby-on-railsrubyruby-on-rails-3delayed-job

Delayed Job with i18n on rails 3


I have this task with delayed_job:

def any_method
 UserMailer.delay(queue: "Email", priority: 3).to_user_when_his_account_is_suspended(user, locale)
end

If I send a email as rails mode:

def any_method
 locale = params[:locale]
 UserMailer.to_user_when_his_account_is_suspended(order, locale).deliver
 #more code
end

The email is sent on the proper locale/language.

However delayed_job does not recognize the proper locale/language. On this case I get locale with locale = params[:locale], you can see the next example:

locale = params[:locale]
UserMailer.delay(queue: "Email", priority: 3).to_user_when_his_account_is_suspended(user, locale)

Mailer Code:

 def to_user_when_his_account_is_suspended(user, locale)
  @user = user
  @locale = locale
  mail(:to => @user.email, :subject => t('.user_account_has_been_suspended'))
 end

How can I fix this problem?


Solution

  • Okay, first, why I think your 'existing' mailer code is working when it's not in DJ.

    Your locale is set through I18n.locale. This is set on a thread specific level...hence, assuming you are setting I18n.locale somewhere for the user, then Rails is using that to send.

    However, DJ will use a separate process entirely...so it can't inherit the locale! This means it will fall back to whatever your default locale is.

    How I'd change your mailer:

    def to_user_when_his_account_is_suspended(user, locale)
      @user = user
      old_locale = I18n.locale
      I18n.locale = locale
      mail(:to => @user.email, :subject => t('.user_account_has_been_suspended'))
      I18n.locale = old_locale
    end
    

    This will temporarily change the language for the thread in the mailer, and then, like a good citizen, it will set it back to the old value at the end of the request.

    Obviously, if you are doing this all over the place, you want to extract it into a helper method that yields control.