This week I worked with background jobs for Rails. It is useful to use Active Job when you're working with API Rest because your app needs to respond ASAP to your client's devices, i.e. web browsers, mobile apps or CLI apps in order to get a better UX. 🚀
Active Job
Active Job is a framework for declaring jobs and making them run on a variety of queuing backends. These jobs can be everything from regularly scheduled clean-ups, to billing charges, to mailings. Anything that can be chopped up into small units of work and run in parallel, really.
Let's suppose you have to update your user's information with some information from another service.
To create a job run the command
rails g job update_user
Rails will create a file called update_user_job.rb
in your app/jobs
folder. You can edit the file and run your needed application logic inside the perform
method
# app/jobs/update_user_job.rb
class UpdateUserJob < ApplicationJob
queue_as :default
def perform(user_id)
user = User.find(user_id)
# let's imagine you're getting external information for your user
metadata = get_some_external_metadata(user.email)
user.update(metadata: metadata)
end
end
Then you need to call your job's perform_later
method whenever you want to execute your job
# app/models/user.rb
after_create :update_metadata
def update_metadata
UpdateUserJob.perform_later(user_id)
end
That's it! Let's take a look at how to test this.
Test your background job
It gets more complicated to test your background jobs because your tests will call the methods but your user fields won't be updated. Your user is being updated in the background! Thanks to Active Job Test Helper we can use some methods to test whether our jobs are being enqueued and updating our users, i.e:
-
assert_enqueued_with
Asserts that the job has been enqueued with the given arguments. -
assert_performed_jobs
Asserts that the number of performed jobs matches the given number. -
perform_enqueued_jobs
Performs all enqueued jobs.
test "update user metadata when created" do
user = user(:one)
assert_enqueued_with(job: UpdateUserJob, args: [user.id])
perform_enqueued_jobs
assert_performed_jobs 1
end
Rspec
If you're using rspec-rails
gem, you have helpers as an alternative to help you test your background jobs. Your tests must set the queue adapter as :test ActiveJob::Base.queue_adapter = :test
and you'll be able to use methods like enqueue_job
and have_been_enqueued
Links:
Top comments (1)
Thanks a ton!