At Agira, Technology Simplified, Innovation Delivered, and Empowering Business is what we are passionate about. We always strive to build solutions that boost your productivity.

,

Active Jobs In Rails – Ruby On Rails Guide

  • By Venkata Krishna
  • September 10, 2018
  • 2413 Views

Active Job is introduced in Rails 4.2 version, Active Job in Rails is a framework for creating, scheduling and executing background Jobs.

What are background Jobs?

The tasks whose execution takes place outside of your normal flow of request-response cycle are the background tasks, these tasks will run parallel to your rails application.

Why we need background Jobs?

For example, your business requirement includes sending a notification email to all your registered users, let us say there are thousand registered users, let us consider it takes 1 second to send an email to the single user, so for sending 1000 users it will take 1000 seconds which is equal to 17 minutes approximately. So you need to wait for 17 minutes to complete the task, this 17 minutes you cannot access any web page of your application since it stops the execution of the task. Practically no user will prefer to wait for that much time without accessing some other web pages of your application.
If you implement the same using background Jobs Since these tasks will run parallelly outside of normal flow of request-response cycle so you no need to wait long for the task to get complete and also you can able to access the other pages of your application too.

When we can use background jobs:

We can use background jobs depending upon the business requirement, and If you want to send a notification email to all users about your latest product then you can go for background jobs, If you want to send your recently published article to all registered users then in that case you can preferably use background jobs likewise it can be applied in some other cases too.

How to create a background Job

We can create Active Job by rails generator using the command

rails generate job job-name

 

The above generator will create a file in app/jobs folder, and it also creates a test case in test/jobs
You can also create a Job without the generator, create a file under app/jobs and inherit your class from ApplicationJob. The file looks in the following manner.
File: app/jobs/send_notifications_job.rb looks in following manner

class SendNotificationsJob < ApplicationJob
    queue_as :default
    def perform(article)
       UserMailer.send_notification_mail(article).deliver_now
    end
end

 

Tips: How To Embed The JW Player Into Website

 

Queueing the Job

If you want to perform your job whenever the queuing system is free then use the below command,

SendNotificationsJob.perform_later(parameters)

 
Note: perform_later and perform_now will call the perform method of your Job. You can also pass as many parameters as you want in the perform method of your Job. You can also schedule your Job, for example, If you want to perform your job after 1 day from now.

SendNotificationsJob.set(wailt_until: Time.now.tomorrow).perform_later(user)

 
You can also set your Job to be performed after 30 minutes from now.

SendNotificationsJob.set(wait: 30.minutes).perform_later(user)

 

Executing The Job

By Default Rails will provide in-process queuing system, in which it keeps the jobs in RAM. The disadvantage of this is, if the machine crashes or if we restart the system, it will cause the loss of existing jobs in the queue. To overcome this disadvantage, you need to add some third party queuing backend where you can queue your Jobs.
There are several built-in adapters of Active Job-like Sidekiq, Resque, Delayed Job, etc. You can choose any one of the built-in adapters as your queuing backend. Here is the list of all adaptors for ActiveJob.

Installing And Configuring the Queuing Backend

Install any of the built-in adapters of the Active job like sidekiq, resque, delayed job, etc. The installation procedure is different for different adapters, please follow specific adapters documentation for installation.
For Sidekiq, please follow the https://github.com/mperham/sidekiq/wiki/Active-Job doc
For Resque, please follow the https://github.com/resque/resque/wiki/ActiveJob
After adding adapter gem to your application, you need to configure the application.rb.

File: app/config/application.rb

Active Job
Here I am using Sidekiq adapter,
So I configured with sidekiq in the config.active_job.queue_adapter, If you are using different adapter, please use that adapter name in the place of sidekiq. Also, if you want to use different queuing backend for specific Job, you can set your queuing backend as follows.

class SendNotificationsJob < ApplicationJob
    self.queue_adapter = :resque
    queue_as :default
    def perform(article)
       UserMailer.send_notification_mail(article).deliver_now
    end
end

This job uses ‘resque’ as its backend queue adapter, It overrides the adapter which you have set in application.rb
Note: before adding the adapter name make sure that you installed adapters gem and followed the installation procedure.

Related: 10 Useful Tips & Tricks for Ruby On Rails Developers

 

Example:

We can do a simple task to send an email to all the registered users using a background job.
Let us consider our business requirement is to send a notification email to all registered users after successful creation of the new article.
I hope you have Ruby on Rails environment setup, next
1) create a simple new rails application by using the command rails new application-name. It will take some time to create your application.
2) Goto the application by cd application-name
3) Add the any one of the adapter gem to your gemfile; we can use sidekiq adapter, so add the line gem ‘sidekiq’ to your gemfile
4) Run the bundler by using the command bundle install
5) Create a user model and database table by using the command rails generate model User name:string email:string
6) Create an article model and database table by using the command rails generate model Article title:string description:text
7) Since we created user table and article table, now run rake db:migrate
8) Now user table is ready, goto rails console by typing rails c in the terminal
9) Create 3 or 4 dummy users but give the valid email address(since we have to send email to that email address). Use this command to create new user User.create(name:’wxyz’, email: ‘valid-email-id’) through rails console, to create multiple users use the same command by changing the name and email.
10) Now you have created users successfully, try User.all command, it should return all the users which you have created.
11) Since our requirement is sending email to users after creating Article, define an Article Controller by using the command rails generate controller Articles new, this command will create a articles controller with one method ‘new,’ it also create new.html.erb under views.

12) We will use Action Mailer to send emails, and Action Mailer allows you to send emails from your application
13) Create an UserMailer by Action Mailer generator; rails generate mailer UserMailer

14) Open your application mailer file and configure default from address, the sender address of all your emails will be the address which you provided in default form. Your file should be as follows

File: app/mailer/application_mailer.rb

 

class ApplicationMailer < ActionMailer::Base
  default from: 'your-from-address-mail-id@domain.com'
  layout 'mailer'
end

 

File: app/config/environments/development.rb

15) Open your development.rb file and give SMTP settings and configure your from address email details

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  :address           => "smtp.gmail.com",
  :port                          => 587,
  :user_name         => 'your-from-address-mail-id@domain.com',
  :password          => 'from-address-main-id-password',
  :authentication    => "plain",
 :enable_starttls_auto => true
}

16) In order to send email to users from your development environment you need change some Gmail settings of receiver email addresses, since Google has increased its security measures it blocks your call as your application is less secure now, click on this link, sign in to your Gmail account and on the Less Secure app access Setting. You will not face this issue in your production environment.
If you enabled less secure app access, it would be like as shown in below image
Active Job
Now we have done all our configurations to send email, and next step is to define a method in app/mailers/user_mailer.rb
I defined a method called send_notification_email which will collect all the user emails and send an email to that email addresses.
File: app/mailers/user_mailer.rb

class UserMailer < ApplicationMailer
     def send_notification_mail(article)
           @article = article
           mail(to: User.pluck(:email), subject: 'Simple Demo to showcase Active Job')
     end
end

We can define the email body by creating the view file under app/views/UserMailer. To create a new file under UserMailer in views, the name of the view file should be same as the method name.

File: app/views/Usermailer/send_notification_mail.html.erb

 

<!-- body of the email -->
<!DOCTYPE html>
<html>
 <head>
<meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
 </head>
 <body>
<h1>Hello</h1>
<p>
  This is a test email to showcase demo of Active Job in Rails.
</p>
 </body>
</html>

15. Our task is to send emails as a background Job using Active Job after creating article successfully in our database. So open your Articles Controller which is located at app/controllers/articles_controller

File: app/controllers/articles_controller

 

class ArticlesController < ApplicationController
  # Initializing the article
  def new
    @article = Article.new
  end
  #  to show the existing article
  def show
    @article = Article.find(params[:id])
  end
  #  Creating the article, executing the background Job after article creation
  def create
       @article = Article.new(article_params)
       if @article.save
  	SendNotificationsJob.perform_now(@article)
  	redirect_to article_path(@article.id)
       else
  	render 'new'
       end
  end
  private
  def article_params
    params.require(:article).permit(:name, :description)
  end
end

new method: This method is used to render the article form for creating the article
show method: This method is used to show the article based on article Id
create method: This method is used to create the article into the articles table, after successful creation we are calling the active job to trigger email, we will see sendNotificationsJob method in upcoming files
article params: This method is used for defining the article parameters
Each method has separate view files which will be under app/views/articles/

File: app/views/articles/new.html.erb

 

<h2>Create Article</h2>
<%= form_for(@article) do |f| %>
  <div>
    <label>Title:</label>
    <%= f.text_field :title %>
  </div>
  <div>
    <label>Description:</label>
    <%= f.text_area :description %>
  </div>
  <%= submit_tag("create Article") %>
<% end %>

This erb template simply renders the form for creating new article.

File: app/views/articles/show.html.erb

 

<h2>Article <%= @article.id %></h2>
<strong>Title</strong>
<%= @article.title %>
<strong>Description</strong>
<%= @article.description %>

This erb template simply displays Article title and Article Description based on Article Id present in URL. Now it is the time to configure the routes.
Open your app/config/routes.rb file and configure your routes as follows

Rails.application.routes.draw do
  get '/articles/:id/show', to: 'articles#show', as: 'article'
  post '/articles', to: 'articles#create'
  root to: 'articles#new'
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

 

Now it is the time to define Background Job.

Open app/jobs/send_notifications_job.rb file and write the code to call the UserMailer’s send_notification_mail method, we are calling this perform method inside the articles controller after creating an article.(see articles_controller code).
File: app/jobs/send_notifications_job.rb

class SendNotificationsJob < ApplicationJob
  queue_as :default
  def perform(article)
    UserMailer.send_notification_mail(article).deliver_now
  end
end

Perform method of SendNotificationsJob will call the userMailer send_notification method.
That’s it we have done all our coding part, now it is the time to execute our code, start your server by using rails s command in terminal. After starting server, access your application using localhost:3000 in the browser.
Active Job
You can see the above form in your browser, Since we are concentrating only on Active Job functionality, I have not added any styles to the application.
Active Job
After entering some sample data in the Article, click create Article button, this will save the record in database and redirect to show template as follows.
Active Job
If you check the emails which you provided at the time of creating users, you will find the new email in your inbox which you triggered from your application. Here is the log file of Active Job.
Active Job
Here are the emails which I received from my application,
Active Job
I hope you understand how we can send email notifications as a background task using Active Job.
Hope this helps you! Similarly you can learn more on interesting on latest technologies, never miss out anything from Our largest blog portal where you can get continuous blog updates & latest posts about all the latest technologies which would be perfect for your 15 minutes tea break! In case if you’re a newbie then don’t forget to subscribe us to get the latest updates from diverse technologies. What else guys hit the subscribe link and go crazy over learning.
For more inquires reach us via info@agiratech.com