delayed_job is a nice gem for executing work in the background in Ruby On Rails.
But what happend to me is that mails did not get send correctly. I was expecting to get them send in german and not english (default locale).
What happend?
The controller did set it correctly depending on the user.
A new record was created that triggered an email to be send. Since delayed_job sends them asynchronously (exactly what i wanted) a job was created in the database and executed in the background.
But the backgroundjob defaulted to the default locale (english) and so the email had the wrong locale that was used for determing translations (I18n.t is used widely in my applications).
So now i had to come up with a solution.
- Remember the locale when the job is created
- set it while executing the job
delayed_job provides a nice API for integrating around job execution (lifecycle-hooks).
So what i did in my task-infrastructure:
1. Add a new Migration for having a attribute locale in the database to store the locale for the job
# Adds a locale attribute to delayed_jobs Table
class AddLocaleToDelayedJobs < ActiveRecord::Migration
def change
change_table :delayed_jobs do |t|
t.string :locale # will hold the locale
end
end
end
2. Add an initializer that stores the locale when a job is created
Delayed::Worker.lifecycle.before(:enqueue) do |job|
# If Locale is not set
if(job.locale.nil? || job.locale.empty? && I18n.locale.to_s != I18n.default_locale.to_s)
job.locale = I18n.locale
end
end
3. Add an initializer that sets the locale around job execution
Delayed::Worker.lifecycle.around(:invoke_job) do |job, &block|
# Store locale of worker
savedLocale = I18n.locale
begin
# Set locale from job or if not set use the default
if(job.locale.nil?)
I18n.locale = I18n.default_locale
else
I18n.locale = job.locale
end
# now really perform the job
block.call(job)
ensure
# Clean state from before setting locale
I18n.locale = savedLocale
end
end
4. Work normally and be happy that localization now also works in the background!
Thanks for this ! Exactly what I wanted to do, and it worked perfectly.
simple ans sweet tx a lot