Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 249
hyperrjas Avatar asked Jan 21 '13 12:01

hyperrjas


People also ask

What is delayed job in Rails?

Delayed Job, also known as DJ, makes it easy to add background tasks to your Rails applications on Heroku. You can also use Resque and many other popular background queueing libraries. Delayed Job uses your database as a queue to process background jobs.

How do I know if my job is running late?

The most simple way to check whether delayed_job is running or not, is to check at locked_by field. This field will contain the worker or process locking/processing the job. Running Delayed::Job. where('locked_by is not null') will give you some results, if there are jobs running.

How do you restart a delayed job?

Restart Delayed Job on deploy You must remove that one now if you have it. It basically does the same thing that we will add now but without using upstart. We will now create a new file that will host our start, stop and restart tasks. Create a file at lib/capistrano/tasks/delayed_job.


2 Answers

This is a better approach, hope it helps somebody:

 def to_user_when_his_account_is_suspended(user, locale)
   @user = user
   I18n.with_locale(locale) do
     mail(:to => @user.email, :subject => t('.user_account_has_been_suspended'))
   end
 end
like image 167
Daniel Benítez Avatar answered Sep 30 '22 16:09

Daniel Benítez


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.

like image 41
Joe Pym Avatar answered Sep 30 '22 16:09

Joe Pym