ActiveRecord's querying API revolves around the concept of lazy loading. When I go in to try to clean up N+1 queries I find myself constantly fighting against the way AR was designed to work, which makes it sooo tempting to say "Meh, computers are fast enough".
This is one of several usability reasons that I've decided to switch to Elixir / Phoenix for all future development work; the Ecto ORM makes it literally impossible to lazy load data; you either load an association at query evaluation time or you don't have the associated data, you need to explicitly query it later on.
One very partial suggestion: Install the Bullet gem and use its Bullet.raise = true setting to crash the app if you see any lazy loading. Troubleshooting with Bullet is awkward because it's fighting against ActiveRecord's natural behavior, so it can only tell you where the N+1 query was lazily triggered, not where in the code the query was originally composed (and where you might need to add includes). But at least with this gem in place you can get part of the information you're seeking:
- Is this code executing obvious N+1 queries?
- Where in the code was the N+1 query triggered?
- What class and association name is the culprit?