Reputation: 48500
When I run queries (e.g. MyModel.where(...)
or record.associated_things
) in the console, how can I see the actual database queries being run so I can gain more understanding of what is happening?
Upvotes: 166
Views: 141031
Reputation: 101
For Rails v"6.1.7.3" the following combination worked for me:
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::LogSubscriber.attach_to :active_record
Upvotes: 8
Reputation: 42474
There are a few configuration parameters that control whether SQL queries are printed to the log.
(This answer is based on Rails 6.0.)
First, confirm that the logger is configured and its @logdev
has a @dev
or @filename
that matches your expectations.
pry(main)> ActiveRecord::Base.logger
=> #<ActiveSupport::Logger:0x00007fd47b400900
...,
@logdev=
#<Logger::LogDevice:0x00007fd47b400a90
@binmode=false,
@dev=#<File:log/development.log>,
@filename="log/development.log",
...>,
...>
Next, ensure that the logger level is set to DEBUG
:
ActiveRecord::Base.logger.debug!
Try running a query to see whether the issue has been fixed:
> ActiveRecord::Base.connection.exec_query 'SELECT 1'
SQL (0.1ms) SELECT 1
If queries are being printed to the log file (e.g. log/development.log
) but not to the console, then you may need to do this:
ActiveRecord::Base.logger.extend(
ActiveSupport::Logger.broadcast(ActiveSupport::Logger.new(STDOUT))
)
If you're still not getting SQL queries, then the ActiveRecord::LogSubscriber
may not be listening to events (e.g. because some libraries deactivate it). Activate it:
ActiveRecord::LogSubscriber.attach_to :active_record
Upvotes: 5
Reputation: 2473
I just wanted to give our production console the same behavior I’m used to on dev, where all SQL queries are reported to the console.
Rails.logger.level = 0
3.0.3 :001 > Rails.logger.level = 0
=> 0
3.0.3 :002 > User.last
User Load (0.7ms) SELECT `users`.* FROM `users` ORDER BY `users`.`id` DESC LIMIT 1
=> #<User:…>
Upvotes: 19
Reputation: 11232
There is the .explain
method in Rails 4.
(.to_sql
works too, but won't show includes)
Category.includes(:products).explain
=> EXPLAIN for: SELECT "categories".* FROM "categories" 0|0|0|SCAN TABLE categories
EXPLAIN for: SELECT "categories_products".* FROM "categories_products" WHERE "categories_products"."category_id" IN (1, 2) 0|0|0|SCAN TABLE categories_products
EXPLAIN for: SELECT "products".* FROM "products" WHERE "products"."id" IN (1, 2, 3, 4, 5, 6, 7) 0|0|0|SEARCH TABLE products USING INTEGER PRIMARY KEY (rowid=?) 0|0|0|EXECUTE LIST SUBQUERY 1
Upvotes: 45
Reputation: 2564
Starting from Rails 6 there is more convenient approach: simply add ActiveRecord::Base.verbose_query_logs = true
in console and you will see all SQL calls and places where it was called. More info https://guides.rubyonrails.org/debugging_rails_applications.html#verbose-query-logs
Upvotes: 13
Reputation: 2500
I prefer to set up logger level in config/application.rb
:
config.after_initialize do
Rails.logger.level = (ENV['LOG_LEVEL'] || Logger::INFO).to_i
end
On production my ENV['LOG_LEVEL']
will be set to the value of Logger::INFO
and on my local machine it'll be Logger::DEBUG
.
Upvotes: 0
Reputation: 115432
Enter this line in the console:
ActiveRecord::Base.logger = Logger.new(STDOUT)
Enter this line in the console:
ActiveRecord::Base.connection.instance_variable_set :@logger, Logger.new(STDOUT)
Upvotes: 361
Reputation: 3440
As from recently, you can use this:
https://github.com/dejan/rails_panel
It consists of developer console panel add-on for chrome, and gem file which needs to be added to your application's Gemfile like this:
group :development do
gem 'meta_request'
end
Then run again:
bundle install
Restart your application, open it, and launch developer console, and you should see it like this:
Upvotes: 6
Reputation: 3621
In Rails 3+ you can use ActiveRecord::Relation’s to_sql
method:
User.where(:id => 3).to_sql
#=> "SELECT \"users\".* FROM \"users\" WHERE \"users\".\"id\" = 3"
Upvotes: 52