Checking for N+1 queries isn't necessarily intuitive. Here's one simple way to verify you have eliminated these pesky queries.
This article isn't meant to review all the nuances of includes, joins, or N+1s but to highlight a technique to check a given query.
Take the following scope:
scope :for_auto_suggest, -> {
includes(:user_verification, :profile_photo_files, { account: [:roles, :career_preference] }, { user_professional_detail: [:specialty] }, { user_practice_contact: [:country] })
}
Because ActiveRecord lazily evaluates queries, running the following on console doesn't necessarily highlight the N+1 problem:
User.for_auto_suggest.limit(3)
However, you can force it to show you the N+1 by requesting the joined attribute you're after:
User.for_auto_suggest.limit(3).map(&:city)
At this point you'll see something that looks suspicious:
City Load (0.4ms) SELECT `cities`.* FROM `cities` WHERE `cities`.`id` = 127817 LIMIT 1
app/models/user.rb:449:in `city_name'
bin/rails:8:in `<top (required)>'
City Load (0.3ms) SELECT `cities`.* FROM `cities` WHERE `cities`.`id` = 102319 LIMIT 1
app/models/user.rb:449:in `city_name'
bin/rails:8:in `<top (required)>'
City Load (0.2ms) SELECT `cities`.* FROM `cities` WHERE `cities`.`id` = 127561 LIMIT 1
app/models/user.rb:449:in `city_name'
bin/rails:8:in `<top (required)>'
By modifying your scope to include the associated model :city
in the correct nested association...:
{ user_practice_contact: [:country, :city ] }
...you can re-run the same scope and the log will look more like this:
City Load (0.3ms) SELECT `cities`.* FROM `cities` WHERE `cities`.`id` IN (127817, 102319, 127561)
bin/rails:8:in `<top (required)>'
This is exactly what you want to see.