3 Easy Steps to optimize Queries in Rails using ‘Bullet’

In the world of web development, performance optimization is a crucial aspect that can make or break the user experience. 

One area that often demands attention is database query optimization. Rails developers, rejoice!

The ‘Bullet’ gem is here to help you fine-tune your database queries and boost your application’s speed and efficiency. In this blog, we’ll delve into the steps to optimize queries in your Rails app using the powerful ‘Bullet’ gem.

First,

let me introduce you to the ‘Bullet’ gem

‘Bullet’ is a ruby gem which facilitates the developers by alerting when an application performs an inefficient database query, such as an N+1 query. It is one of the most efficient tool to optimize a Rails application.

Traditional Method (w/o optimization):

This example illustrates the old-fashioned method of optimizing a query.

For example there are two models, one is Order and other is Product’. And an order has many products. Then the code for order listing page will be

In app/controllers/orders_controller.rb

class OrdersController < ApplicationController
  def index
    @orders = Order.all
  end
end

In app/views/orders/index.html.erb

<h1>Orders</h1>

<% @orders.each do |order| %>
  <div class="order">
    <h2><%=link_to order.title, order_path(order)%></h2>
  </div>
  <%order.products.each do |product|%>
     <ul class=”product”>
        <li><%=link_to product.title, product_path(product)%></li>
     </ul>
  <%end%>
<% end %>

These codes would generate N+1 query issues, because here we have queried just once to get the orders and then separate queries for each order to fetch its products. These sorts of problems can be easily overlooked during development.

‘Bullet’ gem comes in handy for avoiding such problems.

Optimized Method – integrating gem ‘Bullet’:

Let me explain in just 3 easy steps, how the gem ‘Bullet’ can be integrated to optimize the query,

Step#1 – Add the gem to the Gemfile

Example

/Gemfile.rb

  gem 'bullet', '4.6.0', :group => “development”

Run “bundle install” to install the bullet gem in the development group.

Step#2 – Configuration setting in development.rb file

To enable Bullet change its configuration with the after_initialize block in the development.rb file. Set alert as true to get alert popup through the browser.

config.after_initialize do 
    Bullet.enable = true 
    Bullet.alert = true  
    Bullet.bullet_logger = true 
    Bullet.console = true 
    Bullet.rails_logger = true 
  end

Step#3 – Restart the Server

Restart the server as well as reload the page.
After completing the above mentioned steps a JavaScript alert popup would appear with the detected N+1 query. The alert would display the file containing the issue as well as what could be done to overcome the problem.

The previous N+1 query can be fixed by following below mentioned steps:

In Controller,

lass OrdersController < ApplicationController
  def index
    @orders = Order.includes(:products)
  end
end

After changing the statement from ‘Order.all’ to ‘Order.includes’(:products). We can fetch the products through eager loading. Now, if we reload the page we wouldn’t get any alert as we are fetching the efficiently. Here the data is fetched by only two queries, one to get the orders and the other to get the products in those orders.

‘Bullet’ can also tell us when we’re doing eager loading unnecessarily. Let’s say in the order listing page only order will be displayed. So, we removed the code that was displaying the list of products. Now after reloading the page we will get an alert popup displaying that Bullet has detected unused eager loading.

Step 4: Run Your App

With ‘Bullet’ enabled, navigate through your application by using its various features. ‘Bullet’ will keep a close eye on your queries and provide alerts if it detects N+1 query problems or suggests eager loading opportunities.

Step 5: Review Alerts

As you interact with your app, pay attention to any alerts generated by ‘Bullet.’ It will notify you about potential N+1 query issues, which occur when a single query fetches associated records for multiple main records, leading to excessive database hits.

Step 6: Eager Loading Optimization

When ‘Bullet’ suggests eager loading, take action by optimising your queries. Use ActiveRecord includes or eager_load methods to load associated records in advance, reducing the need for multiple queries.

Benefits:

  • No need to search the codes in each file to figure out the inefficient database query.
  • Bullet can notify us, through an alert message, by writing in the console or in the log file.
  • Prevent our application from performing an inefficient database query like an N+1 query.
  • It can also detect unused eager loading.

Conclusion

The ‘Bullet’ gem is a powerful tool that empowers Rails developers to optimize their application’s database queries and improve overall performance. 

By following the step-by-step guide outlined in this blog, you can easily integrate ‘Bullet’ into your development workflow, identify potential N+1 query problems, and capitalize on eager loading opportunities. 

Embrace the ‘Bullet’ gem and take your Rails app’s speed and efficiency to new heights, ensuring a seamless and delightful user experience.

Related Questions

Q1: What is the main purpose of the ‘Bullet’ gem in a Rails application?

Ans:
The ‘Bullet’ gem serves as a performance optimization tool in Rails applications. It monitors queries and helps identify potential N+1 query issues and opportunities for eager loading, ultimately optimizing database queries for improved application performance.

Q2: What steps are involved in installing and configuring the ‘Bullet’ gem for query optimization?

Ans:
To optimize queries using the ‘Bullet’ gem, start by adding it to your Gemfile. After installation, configure the gem in your config/environments/development.rb file by enabling it, enabling alerts, and setting up bullet logging. This allows ‘Bullet’ to monitor and alert you about query-related issues.

Q3: How does the ‘Bullet’ gem help in identifying N+1 query issues?

Ans:
The ‘Bullet’ gem identifies N+1 query problems by analyzing your application’s query patterns. If it detects instances where multiple queries are being executed to retrieve associated records for a main record, it generates alerts. These alerts prompt developers to address the issue and optimize queries through eager loading.

Q4: What is eager loading, and how does the ‘Bullet’ gem assist in optimizing it?

Ans:
Eager loading is a technique to fetch associated records in advance to avoid N+1 query problems. The ‘Bullet’ gem suggests opportunities for eager loading by analyzing query patterns. When an N+1 query issue is detected, ‘Bullet’ recommends using ActiveRecord’s includes or eager_load methods to load associated records efficiently.

Q5: What are the benefits of using the ‘Bullet’ gem for query optimization in Rails applications?

Ans:
Using the ‘Bullet’ gem offers several benefits, including optimized queries that reduce database hits, enhanced application performance, increased developer productivity through quick problem identification, and efficient use of eager loading to minimize query-related issues. Overall, it leads to a smoother user experience and improved application responsiveness.

Steps to execute pagination using “Kaminari” gem in Rails3

Pagination is a technique that divides content into manageable chunks, allowing users to easily browse through a dataset. 

In this blog, we’ll dive into the process of implementing pagination using the “Kaminari” gem in a Rails 3 application. 

Kaminari is a powerful and flexible gem that simplifies the pagination process, enhancing the performance and usability of your web application.

Key Features:

  • Easy to use.
  • Customizable engine-based I18n-aware helper.
  • The pagination helper outputs the HTML5 <nav> tag by default and the helper supports Rails 3 unobtrusive Ajax.

Recommended Reading: AJAX Pagination using jQuery in Rails3

Here are the steps to implement “kaminari gem” in a Rails app.

Step#1

  • Put this code in your Gemfile:

[sourcecode]gem ‘kaminari'[/sourcecode]

  • Run “bundle install”

Step#2

  • Modify the controller as mentioned below

[sourcecode]@blogs = Blog.order("name").page(params[:page])[/sourcecode]

Step#3

  • Now, add the paginate helper method in your listing page which is provided by Kaminari, by passing in the list we’re paginating.

[sourcecode]<%= paginate @blogs%>[/sourcecode]

Step#4

  • When the page reloads, the pagination links will be visible. Kaminari will show 25 items per page by default, but we can easily change that by calling another scope called “per” as mentioned below.

[sourcecode]@blogs = Blog.order("name").page(params[:page]).per(10)[/sourcecode]

  • Now it should display 10 items per page.

Step#5

  • You can configure the below mentioned default values of kaminari by running the command

[sourcecode]rails g kaminari:config[/sourcecode]

It’ll generate a file “kaminari_config.rb” in your config/initializers folder with the following code snippet as commented.

[sourcecode]
default_per_page # 25 by default
max_per_page # nil by default
window # 4 by default
outer_window # 0 by default
left # 0 by default
right # 0 by default
page_method_name # :page by default
param_name # :page by default[/sourcecode]

  • Next, you can change the values according to your requirement.
  • If you change your view page like:

[sourcecode]<%= paginate @blogs, :window => 2 %> [/sourcecode]

  • The output will be:

[sourcecode]« First ‹ Prev 1 2 3 4 5 … Next › Last »[/sourcecode]

  • There are some other custom attributes you can use in view page like:

[sourcecode]
<%= paginate @users, :outer_window => 3 %>
<%= paginate @users, :left => 1, :right => 3 %>
<%= paginate @users, :params => {:controller => ‘foo’, :action => ‘bar’} %>
<%= paginate @users, :remote => true %> [/sourcecode]

Kaminari also includes a handy template generator. You can override them by running following command.

[sourcecode]rails g kaminari:views default[/sourcecode]

It’ll generate a “Kaminari” folder in app/views with dependent files inside it.

I hope you liked it. If you want you can contact our experienced ruby on rails developer for your webs and mobile application.
Please leave your comment about this post on the comment section below.

You’re just 2 steps away from implementing ‘Backbone’ in Rails 3

backbone1-300x300-123

Before illustrating steps to implement ‘Backbone.js’, let me explain what ‘Backbone.js’ really is. It is a convenient way to organize client side ‘JavaScript’ code into MVC pattern of Rails server applications. Just like in Rails, It has ‘Models’ to represent data, ‘Views’ to render it and ‘Controllers’ to coordinate between the two. It also has an object called “collection” which manages a list of models. Backbone was also designed with Rails backend in mind, and is easier to connect to a server application using JSON in order to transfer data back and forth.

Why need to implement ‘Backone.js’ into Rails applications:

  • The major advantage of “Backbone.js” is that it’s simple, lightweight, and provides structure to organize large JavaScript projects.
  • “Backbone.js” helps to reduce the load of server for code that really doesn’t need to be executed server-side.
  • Flexible with regards to data persistence.
  • Easier integration with RESTful interfaces.
  • “Backbone.js” gives structure to web applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing API over a RESTful JSON interface.

Architecture of “Backbone.js”

Integration

Step#1

  • In rails 3.x

In Gemfile add below line

[sourcecode]gem ‘rails-backbone'[/sourcecode]

Run “bundle install”

Then install “Backbone.js” in the app by running the following command

[sourcecode]rails g backbone:install[/sourcecode]

This creates the following Directory structure under app/assets/javascripts/backbone.

[sourcecode]backbone/
routers/  (maps HTML routes to actions)
models/  (maintains state)
templates/ (presents clientside views)
views/ (presents model data in the DOM)[/sourcecode]

To setup initial requirements and name spacing, it also creates a coffee script file as app_name.js.coffee.

[sourcecode]app/assets/javascript/backbone/app_name.js.coffee[/sourcecode]

Step#2

It also provides 3 simple generators which only create client side JavaScript code

Create a backbone model and collection inside app/assets/javascripts/backbone/models to be used to communicate with rails backend.

[sourcecode]rails g backbone:model model_name field_name:datatype[/sourcecode]

Create a backbone router with corresponding views and templates for the actions.

[sourcecode]rails g backbone:router[/sourcecode]

For Scaffolding

[sourcecode]rails g backbone:scaffold[/sourcecode]

Example

Create a new rails application called Demo

[sourcecode]rails new Demo[/sourcecode]

Edit, /Gemfile.rb

[sourcecode]gem ‘rails-backbone'[/sourcecode]

Install the gem and generate scaffolding by running following commands

[sourcecode]bundle install
rails g backbone:install
rails g scaffold Job title:string description:string
rake db:migrate
rails g backbone:scaffold Job title:string description:string[/sourcecode]

Edit the jobs index view (app/views/jobs/index.html.erb)

[sourcecode]<div id="jobs"></div>
<script type="text/javascript">
$(function() {
// Demo is the app name
window.router = new Demo.Routers.JobsRouter({jobs: <%= @jobs.to_json.html_safe -%>});
Backbone.history.start();
});

</script>[/sourcecode]

Now start the server

[sourcecode]rails s[/sourcecode]

Then browse “localhost:3000/jobs” and now you will get a fully functioning single page crud app for Job model.

Benefits of implementing backbone on Rails application:

  • ‘Backbone’ speeds up loading of WebPages.
  • Backbone implementation is comparatively easier for the developers working on JavaScript applications.
  • It uses minimal set of data-structuring (Models and Collections) and user interface (Views and URLs).
  • It also facilitates in improving and maintaining the application structure.

4 Simple Steps To Implement “Delayed Job” In Rails

Here in this article, I going to tell you the best way to implement “delayed job” in rails

“delayed_job” is a ruby gem used to execute tasks as a background process in Rails environment, increasing page rendering speed.

Delayed::Job (or DJ) allows you to move jobs into the background for asynchronous processing.

Why you need a background process and is it really that important!

Let’s consider a scenario where a mailing application needs to send emails to a huge list of recipients. In such cases it is obvious that the processing time is too long, annoying the users.

Here are some of key points to consider:

  • Incredibly quick & easy to get rolling
  • No addition to your “stack”, runs just fine with Active Record
  • Good choice for beginners while migrating code from foreground to the background

Hence, it’s only wise to move the long running tasks as a background process by using “delayed_job” gem.

Detailed steps to integrate delayed job in a Rails application

Step# 1

  • Add gem to the Gemfile
  • “delayed_job” supports multiple back-ends for storing the job queue
  • To use “delayed_job” with Active Record, use gem ‘delayed_job_active_record’
  • To use “delayed_job” with Mongoid, use gem ‘delayed_job_mongoid’

Example

/Gemfile.rb

  • gem ‘delayed_job_active_record’, ‘4.0.3’
  • Run “bundle install” to install the “delayed_job” gem

Step# 2

  • Generate the related file for the Job run
  • Generate related files required to run the background job by running the following command
    • rails g delayed_job:active_record

It adds following files to the application

  • A Script named “delayed_job” inside “/bin” folder to run the jobs which are in queue.
  • Migration file to create a table to store the job with other information such as priority, attempts, handler, last_error, run_at, locked_at, failed_at, locked_by, queue.

Run the migration file by using the following command

  • rails db:migrate

Set the queue_adapter in config/application.rb

  • config.active_job.queue_adapter = :delayed_job

If you are using the protected_attributes gem, it must appear before delayed_job in your gemfile. If your jobs are failing with:

  • Setup Delayed::Job config in an initializer (config/initializers/delayed_job_config.rb)
    • Delayed::Worker.destroy_failed_jobs = false
    • Delayed::Worker.sleep_delay = 60
    • Delayed::Worker.max_attempts = 3
    • Delayed::Worker.max_run_time = 5.minutes
    • Delayed::Worker.read_ahead = 10
    • Delayed::Worker.default_queue_name = ‘default’
    • Delayed::Worker.delay_jobs = !Rails.env.test?
    • Delayed::Worker.raise_signal_exceptions = :term
    • Delayed::Worker.logger = Logger.new(File.join(Rails.root, ‘log’, ‘delayed_job.log’))

Step# 3

  • Replace script/delayed_job with bin/delayed_job
  • Start up the jobs process

There are two ways to do this.

  • If application is in development mode, we would use the below rake task instead.
    • rake jobs:work
  • If application is in production mode, then it is preferred to use the “delayed_job” script. This demonizes the job process and allows multiple background processes to be spawned.

To use this, pursue the following steps

  • Add gem “daemons” to your Gemfile
  • Run bundle install
  • Make sure you’ve run rails generate delayed_job
  • If you want to just run all available jobs and exit you can use rake jobs:workoff
  • Work off queues by setting the QUEUE or QUEUES environment variable.
    • QUEUE=tracking rake jobs:work
    • QUEUES=mailers,tasks rake jobs:work

Step# 4

  • Add task to run in background
  • In Controller just call .delay.method(params) on any object and it will be processed in the background.

Example:

UsersController before adding to background job

[code language=”html”]
class UsersController < ApplicationController
def send_email
User.find_each(is_subscribed: true) do |user|
NewsMailer.newsletter_mail(user).deliver
flash[:notice] = "Mail delivered"
redirect_to root_path
end
end
end
[/code]

 
UsersController after adding to background job

[code language=”html”]
class UsersController < ApplicationController
def send_email
User.find_each(is_subscribed: true) do |user|
# add .delay method to add it to background process. In case of mail sending remove the .deliver method to make it work.
NewsMailer.delay.newsletter_mail(user)
flash[:notice] = "Mail delivered"
redirect_to root_path
end
end
end
[/code]

Advantages of implementing above steps:

  • No more waiting for a response, after clicking a link to do a big stuff.
  • Just call .delay.method(params) on any object and it processes in the background.
  • Job objects are serialized to yaml and stored in the delayed_jobs table, so they can be restored by the job runner later.
  • It automatically retries on failure. If a method throws an exception it’s caught and the method reruns later. The method retries up to 25 times at increasingly longer intervals until it passes.
  • “delayed_job” gem maintains log by creating a log file “/log/delayed_job.log”

I am sure this article will give you a clear idea about the way to implement “delayed job” in rails. You can share your thoughts with comments if I have missed anything or if you want to know more.

Do you work on or use Ruby on Rails? Let’s Discuss!

Ruby On Rails Releases Fixes For DoS, XSS Vulnerabilities

In 18th March, Ruby on Rails released four new versions along with fixes for a number of vulnerabilities, which could have lead to denial of service attacks and XSS injections. According to a post in company’s blog a total of 4 vulnerabilities were addressed in version 3.2.13, 3.1.12 and 2.3.18 of Rails. The company wrote “All versions are impacted by one or more of these security issues,”

The patches were released for symbol denial service (DoS) vulnerability (CVE-2013-1854) in ActiveRecord function and for two cross-sites scripting vulnerabilities i.e. sanitize helper (CVE-2013-1857) and sanitize_css method in Action Pack (CVE-2013-1855).

According to one of the warnings, an additional XML parsing vulnerability in JDOM backend of ActiveSupport could have also allowed attackers to perform denial of service attack when using JRuby (CVE-2013-1856) or could have enabled to gain access to files stored in the app server.

The XSS vulnerability could have allowed attackers to embed tag URL, which executes arbitrary JavaScript code.

The XSS vulnerabilities in particular could have allowed an attacker to embed a tag containing a URL that executes arbitrary JavaScript code.

Ruby on rails developer have fixed a number of similar issues in Ruby on Rails last month, which also included a YAML issue in ActiveRecord that lead to remote code execution

Top Reasons To Bring RoR Development On Board

ror411-123

Rails is an innovation in development framework.  It encompasses all the necessary elements to boost a web application’s performance. This framework is designed to address agile development and deliver productivity as well as flexibility to RoR developers. Developed using Ruby programming language, it has transformed the world of web development through its practical approach.

Ruby on Rails is built upon two programming philosophies

  • “Convention over Configuration”: Developers only need to write codes for the irregular or unconventional aspects of the web application.
  • “Don’t Repeat Yourself”: The data is stored in definite place. It saves time and reduces code

Advantages of Ruby on Rails

  • Faster Development: Rails framework enables the developers to write concise and clear syntax and produces fewer codes than its competitors. Therefore it requires less time to code and generates fewer errors. On the other hand it facilitates the programmers to maintain much less code. It is also enabled to integrate numerous tools to automate repetitive tasks such as managing database errors, creating forms etc. it simplifies development process because the language is lightweight and easily readable, almost like the natural language.
  • Increases productivity: Rails framework is specifically featured to reduce the development aspects of applications, instead leveraging creativity and uniqueness of the web application. It empowers productivity by eliminating repetitive programming codes.
  • Assists development of creative interfaces: Rails includes numerous integrations to enable developers in creating rich, intriguing user interfaces. Integrated JavaScript framework is easier to activate and features elements like apparition progressive, drag & drop and many more to ease the designing aspects of the application.
  • Model View Controller design pattern: Rails is developed on MVC architecture that separates the development logics from the presentation layer. It provides a well-structured application to the developers and the code is maintained in a logical and coherent manner.  It encourages abstraction in the application and enables the team to work on separate modules without depending on each other. It focuses on the features rather than minute details. Rails framework delivers ease of project development, conciseness and faster deployment of application.

Rails Development makes web app development easier because it involves less coding while implementing new changes and updates into the development process. It enables the organizations to meet all the business requirements within the budget and schedule.