🔍 why_query

Find out exactly where your SQL queries come from.
No more grepping logs or blaming ActiveRecord. why_query prints the file and line of code that triggered every query in development.

User.where(active: true).first
# => ↳ Called from: app/controllers/users_controller.rb:12

✨ Features

  • 📍 Logs where each SQL query was called from
  • 🧠 Filters to your app code only (no gems, no noise)
  • 🛠 Simple configuration (log anywhere, toggle anytime)
  • 🧪 Great for debugging N+1s and finding rogue queries

🚀 Installation

Add it to your Gemfile:

gem "why_query", group: :development

Then run:

bundle install

⚙️ Configuration

Create an initializer in your Rails app:

# config/initializers/why_query.rb

WhyQuery.configure do |config|
  config.enabled = Rails.env.development?       # Toggle globally
  config.app_only = true                        # Only log queries from your app files
  config.logger = ->(msg) { Rails.logger.debug("[WHY_QUERY] #{msg}") } # Custom logger
end

You can also toggle at runtime:

WhyQuery.config.enabled = false

💡 Output Examples

In logs or console:

SELECT "users".* FROM "users" WHERE "users"."active" = TRUE
↳ Called from: app/services/users/fetcher.rb:7

❓ Why Use This?

  • “Where did this query come from?”
  • “Who’s loading all users in a loop?”
  • “Why is my controller generating 20 queries?”

Now you’ll know. Instantly.


🧠 Tips

Want to log stack traces? Set app_only = false:

WhyQuery.configure do |config|
  config.app_only = false
end

You’ll get:


🙏 Acknowledgements

Inspired by hours of wondering “Where the heck is this query coming from?”