23 May How to prevent n + 1 queries using Rspec with the usage of ActiveSupport::Notifications.subscribed
I have seen many times that I forget to lazy load associations when doing queries and that generates n + 1 queries, in order to avoid and reduce these errors most of the time I add some scenarios in rspec that prevents `n + 1 queries` using a simple helper in rspec:
spec/support/query_limit.rb
module Common
module Helpers
def print_queries_generated_for &block
counter_f = ->(name, started, finished, unique_id, payload) {
unless payload[:name].in? %w[ CACHE SCHEMA ]
puts "====================================="
puts payload
puts "====================================="
end
}
ActiveSupport::Notifications.subscribed(counter_f, "sql.active_record", &block)
end
def count_queries_for &block
count = 0
counter_f = ->(name, started, finished, unique_id, payload) {
unless payload[:name].in? %w[ CACHE SCHEMA ]
count += 1
end
}
ActiveSupport::Notifications.subscribed(counter_f, "sql.active_record", &block)
count
end
end
end
spec/rails_helper.rb or spec/spec_helper.rb
config.include Common::Helpers
Usage:
it 'does not make a n + 1 queries' do
result = count_queries_for do
get :index, { format: :json, version: 1 }
end
expect(result).to eq(1)
end
or
it 'does not make a n + 1 queries' do
result = count_queries_for do
SurveyRespondent.count
end
expect(result).to eq(1)
end
If you want to see the output of the queries involved in that scope or endpoint use the method:
print_queries_generated_for do
get :index, { format: :json, version: 1 }
end
That’s it
No Comments