🔍 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?”