Scheduling Tasks in Ruby on Rails using Whenever Gem
As a back-end developer, most of your time is dedicated to either creating APIs that will be utilized by web or mobile clients or generating views for data display.
When using a back-end framework like Rails, it is common to require specific code to be executed at particular times. For instance:
- Send weekly product updates to customers
- Send daily news updates at a specific time to users
- Check unfinished checkouts every 10 minutes and remind customers to finish them
- Send monthly statement on every 1st of the month
- Send a To-Do list every day in the morning
As you may observe, it could be necessary to run our code on a recurring schedule, be it every minute, hour, day, or on a specific date of the month. Although the examples commonly involve tasks like sending an email, it is not exclusively restricted to that. In essence, Rails code can be executed at any time. Here is how:
Introduction to Cronjobs
A cronjob is a utility in Unix-based operating systems that allows users to schedule and automate the execution of commands or scripts at specific intervals.
Cronjobs are often used in server-side web development to perform routine tasks such as database backups, log cleaning, and periodic maintenance. They can also be used to run recurring processes.
To set up a cronjob, a user creates a cron table entry specifying the command or script to be executed and the schedule at which it should run. The schedule is defined using a combination of time and date fields that specify when the command should be executed, such as every minute, hourly, daily, weekly, or monthly.
Whenever Gem
Thankfully, in Rails there are several gems available to simplify the task, and Whenever gem is one of them. All you need to do is to focus on your Ruby code. Below is the step-by-step guide to including Whenever Gem in your project.
Step 1: Create a new project
Create a new rails project:
$ rails new cron_tutorial
Step 2: Adding Whenever Gem
Let’s navigate inside the project directory:
$ cd cron_tutorial
Open Gemfile in your favorite text editor and add the following at the end of the Gemfile:
gem 'whenever', :require => false
Tip: The :require => false
option is used to tell Bundler not to load the gem at startup. This means that the gem will not be loaded until it is explicitly required in the code, which can help improve the performance of your application.
Step 3: Bundle Install
Run the following command at the root directory of your project:
$ bundle install
Next, run the following command to initialize the setup.
$ bundle exec wheneverize .
This will create a config/schedule.rb file in your project.
Step 4: Getting the code ready
We are all set to run the code using Whenever. For this let’s create a simple User model and add some code that will be executed through cronjob.
Creating Customer model
Write the below command to create a simple customer model.
$ rails generate model Customer name:string email:string --no-test-framework
Tip: — no-test-frameowrk will not generate any test files. This is for simplification.
Migrate the database:
$ rails db:migrate
Let’s add a simple method in the customer model to output customer count every minute:
class Customer < ApplicationRecord
def self.customer_count
#
puts "Cutomer count at #{Time.now} is : #{Customer.count}"
end
end
We’ll call the above method in the schedule.rb as follows:
set :output, "log/cron_output.log"
every 1.minutes do
runner "Customer.customer_count"
end
Notice that we’ve set the output logs to a separate file.
Step 5: Executing The Cronjob
All we need to do now is to update the crontab file in the system. This can be done using the following command:
$ whenever --update-crontab --set environment=[YOUR_ENV]
Replace your environment name in the above command. If you are running locally, it might be ‘development’.
After the above command succeeds, open the cron_output.log file and notice the logs are generating. I created a customer using the rails console and you can see the customer count changed. Here’s what you can do as well:
$ rails c
> Customer.create(name: 'john',email: 'john@example.com')
Now that you have a basic idea about Task scheduling in Rails, you can also explore the documentation of the gem here.
You can get the complete code from GitHub