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