Integrating Cron Job in Rails 4 Project

Recently I have been assigned a job where all users of the system should be charged after every 30 days. So, I need to find out a system of running my transaction process periodically.How can I do it automatically? After some googling, I figured out ‘Cron Job’ as the suitable answer of my query. Now, another question arises. How to integrate Cron Job in Rails 4 project using Ruby? Here we go:

Often we need to handle recurring processes or tasks or background jobs something like mailing after a definite period of time or rolling log files or charged client at end of month etc. There are a lot of ways, but among them most common is to use corn. The software utility Cron is a time-based job scheduler in Unix-like computer operating systems.

In Ruby / Rails world there are plenty of options for background processing but most of them are not that simple and easy to being with. A Ruby gem named Whenever allows us to write corn jobs in Ruby using a much simpler syntax.

Installing Whenever

To begin with include Whenever in your Gemfile

gem 'whenever', require: false

And then run

bundle install

Check your Whenever gem version as you need to use gem version >= 0.8.4 if want to be compatible with Rails 4. You can check the version by following command

whenever -v

Now that the Whenever gem is installed we can run the wheneverize command to set it up. We have to pass it the path to the Rails application, which will just be “.” if you’re in your application’s directory.

wheneverize .

Output will be like this:

[add] writing `./config/schedule.rb'

[done] wheneverized!

This command will create a schedule.rb file in the config directory. We will write our cron job here.

Writing our first Cron Job

Let’s create a job that will run every three hours.

every 3.hours do
runner "MyModel.some_process"
rake "my:rake:task"
command "/usr/bin/my_great_command"

In each job we can run Ruby code with script/runner, execute rake tasks or run any external command that we choose. Whenever will also automatically handle the behind-the-scenes work, moving to your Rails app’s directory, running the rake tasks in production mode and so on.

Alternatively, instead of specifying a time period we can use certain keywords.

every :reboot do
rake "run_seed_db:start"

We can use any day of the week or :weekend, :weekday

every :sunday, :at => '12pm' do
runner "Task.do_something_great"

Lets say that the size of our cache files is getting out of hand so we want to clear out the cache folder every Friday morning at 4am. We can do this by running rm in the cache folder.

every :friday, :at => "4am" do
command "rm -rf #{RAILS_ROOT}/tmp/cache"

Whenever ships with three pre-defined job types: command, runner, and rake. We can define your own with job_type.

For example:

job_type :awesome, '/usr/local/bin/awesome :task :fun_level'

every 2.hours do
awesome "party", :fun_level => "extreme"

Would run /usr/local/bin/awesome party extreme every two hours. :task is always replaced with the first argument, and any additional:whatevers are replaced with the options passed in or by variables that have been defined with set.

Generate the Corn Job

Suppose we have written a cron job in schedule.rb for charging all client’s under our system monthly.

every 30.days, :at => '12:00 am' do
runner 'MonthlyBillingService.execute_transaction'

To create the actual cron job.

whenever --update-cron theNameOfCronJob

Example: whenever --update-crontab bill here ‘bill' is the name of our corn job.The identifier is important as it ensures that the correct cron jobs are updated when we change our schedule.rb file

This will create an output like this.

write crontab file updated

After we run the command we can open the crontab file with crontab -l and see the jobs that Whenever has added.

# Begin Whenever generated tasks for: bill

0 0 1 * * /bin/bash -l -c 'cd /home/rony/Projects/TestCronJob && bin/rails runner -e production '\''MonthlyBillingService.execute_transaction'\'' >> log/cron.log 2>&1'

# End Whenever generated tasks for: bill

Change in Job

We can easily change our job nature and description. Whenever makes it so simple. We just change the job as like we want in schedule.rb and then rerun whenever.

For example we have changed our corn job by rescheduling it to run after every 25 days at 10.00 pm

every 25.days, :at => '10:00 pm' do
runner 'MonthlyBillingService.execute_transaction'

If we check our corntab file now using crontab -l command we will get the updated file.

# Begin Whenever generated tasks for: bill
0 22 25 * * /bin/bash -l -c 'cd /home/rony/Projects/pro && bin/rails runner -e production '\''MonthlyBillingService.execute_transaction'\'' >> log/cron.log 2>&1'
# End Whenever generated tasks for: bil

For details about Whenever please read the documentation here.

Happy Coding!!! 😀


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s