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)