How to detect N+1
Prosopite
Install
gem install prosopite
bundle add prosopite
# Gemfile
gem 'prosopite'
Configure
Controller
Add the following to ApplicationController
class ApplicationController < ActionController::Base
unless Rails.env.production?
before_action do
Prosopite.scan
end
after_action do
Prosopite.finish
end
end
end
Enable logging
# config/environments/development.rb
config.after_initialize do
Prosopite.rails_logger = true
end
Spec
# config/environments/test.rb
config.after_initialize do
Prosopite.rails_logger = true
Prosopite.raise = true
end
# spec/spec_helper.rb
config.before do
Prosopite.scan
end
config.after do
Prosopite.finish
end
Now everytime you run the test, you will be able to see any error about N+1 queries.
Note: It won't raise any exception if only one association.
For example
class Teacher < ActiveRecord
has_many :students
end
class Student < ActiveRecord
belongs_to :teacher
end
No exception
teacher = Teacher.create(name: 'John')
teacher.students.create(name: 'Tom')
Teacher.first.students do |student|
puts student.name
end
Throw exception about N+1
teacher = Teacher.create(name: 'John')
teacher.students.create(name: 'Tom')
teacher.students.create(name: 'Jerry')
Teacher.first.students do |student|
puts student.name
end
Prosopite::NPlusOneQueriesError:
N+1 queries detected:
SELECT `students`.* FROM `students` WHERE `students`.`id` = ? LIMIT ?
Top comments (0)