170

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?

2

9 Answers 9

366

Rails 3+

Enter this line in the console:

ActiveRecord::Base.logger = Logger.new(STDOUT)

Rails 2

Enter this line in the console:

ActiveRecord::Base.connection.instance_variable_set :@logger, Logger.new(STDOUT)
Sign up to request clarification or add additional context in comments.

5 Comments

Perfect, just what I needed. Have any recommendation where to go find small tricks such as these are documented?
This works for rails 3+ but not 2, see stackoverflow.com/a/1576221 if you're there still :)
And to disable it again: ActiveRecord::Base.logger = nil
I've been here so many times, when I type "rails" in chrome, it displays this page as the top result
53

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"

Comments

46

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

1 Comment

It took me so much time to find the .explain will do the job and not .to_sql. And .explain still does not provide sql query in raw format which I can run in pg console. But I needed the raw query to explain and analyze. I guess will have to do with explain for now.
19

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:…>

1 Comment

Equivalent to Rails.logger.level = :debug
13

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

3 Comments

There should be no need to turn it on, anymore, as it should be nowadays on by default: "Verbose query logs are enabled by default in the development environment logs after Rails 5.2."
This seems to be deprecated: "ActiveSupport::DeprecationException: DEPRECATION WARNING: ActiveRecord::Base.verbose_query_logs= is deprecated and will be removed in Rails 7.1."
This method has indeed been deprecated, but it was moved out of AR::Base and is now available as ActiveRecord.verbose_query_logs as of Rails 7.0.
9

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

Comments

6

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: enter image description here

Comments

6

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

Comments

0

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.