我怎样才能看到由Ruby on Rails中给定的ActiveRecord查询生成的SQL

我想看看给定的ActiveRecord查询将生成的SQL语句。 我知道我可以从查询发布后,从日志中获取这些信息,但我想知道是否有一个方法,可以调用和ActiveRecord查询。

例如:

SampleModel.find(:all, :select => "DISTINCT(*)", :conditions => ["`date` > #{self.date}"], :limit => 1, :order => '`date`', :group => "`date`") 

我想打开irb控制台,并在最后加上一个方法来显示此查询将生成的SQL,但不一定执行查询。

当最后我试图做到这一点,没有官方的方式来做到这一点。 我使用了find和它的朋友用来直接生成查询的函数。 这是私有的API,所以Rails 3将会完全破坏它,但是对于debugging来说,这是一个很好的解决scheme。

方法是construct_finder_sql(options)lib/active_record/base.rb:1681 )你将不得不使用send因为它是私人的。

编辑construct_finder_sql 在Rails 5.1.0.beta1中被删除 。

与penger类似,但是即使在类已经加载并且logging器已经被caching之后,仍然可以在控制台中工作:

对于Rails 2:

 ActiveRecord::Base.connection.instance_variable_set :@logger, Logger.new(STDOUT) 

对于Rails 3.0.x:

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

对于Rails> = 3.1.0,这已经在控制台中默认完成了。 如果它太嘈杂,你想关掉它,你可以做:

 ActiveRecord::Base.logger = nil 

在某处puts query_object.class一个puts query_object.class来查看你的工作types,然后查找文档。

例如,在Rails 3.0中,作用域使用具有#to_sql方法的ActiveRecord::Relation 。 例如:

 class Contact < ActiveRecord::Base scope :frequently_contacted, where('messages_count > 10000') end 

那么,你可以做的地方:

 puts Contact.frequently_contacted.to_sql 

这可能是一个老问题,但我使用:

 SampleModel.find(:all, :select => "DISTINCT(*)", :conditions => ["`date` > #{self.date}"], :limit=> 1, :order => '`date`', :group => "`date`" ).explain 

explain方法将提供相当详细的SQL语句

只是使用to_sql方法,它会输出将被运行的SQL查询。 它工作在一个活跃的logging关系。

 irb(main):033:0> User.limit(10).where(:username => 'banana').to_sql => "SELECT "users".* FROM "users" WHERE "users"."username" = 'banana' LIMIT 10" 

find ,它将无法正常工作,因此您需要手动将该ID添加到查询中或使用where来运行。

 irb(main):037:0* User.where(id: 1).to_sql => "SELECT "users".* FROM "users" WHERE "users"."id" = 1" 

这是我通常会在控制台中获取SQL的方式

 -> script/console Loading development environment (Rails 2.1.2) >> ActiveRecord::Base.logger = Logger.new STDOUT >> Event.first 

当你第一次启动控制台的时候你必须这么做,如果你在input代码之后这样做,它似乎不起作用

不能真正承认这一点,很久以前从别人的博客发现,不记得是谁的。

在您的主目录中创build一个.irbrc文件并将其粘贴到:

 if ENV.include?('RAILS_ENV') && !Object.const_defined?('RAILS_DEFAULT_LOGGER') require 'logger' RAILS_DEFAULT_LOGGER = Logger.new(STDOUT) end 

这将输出SQL语句到你的irb会话。

编辑:对不起,将仍然执行查询,但它是最接近我知道的。

编辑:现在用arel,只要对象返回ActiveRecord :: Relation并调用.to_sql就可以build立范围/方法,并且它将把要执行的sql。

试试show_sql插件 。 该插件使您能够打印SQL而不运行它

 SampleModel.sql(:select => "DISTINCT(*)", :conditions => ["`date` > #{self.date}"], :limit => 1, :order => '`date`', :group => "`date`") 

您可以更改连接的日志方法以引发exception,防止查询运行。

这是一个彻头彻尾的黑客,但它似乎为我工作(Rails的2.2.2,MySQL的):

 module ActiveRecord module ConnectionAdapters class AbstractAdapter def log_with_raise(sql, name, &block) puts sql raise 'aborting select' if caller.any? { |l| l =~ /`select'/ } log_without_raise(sql, name, &block) end alias_method_chain :log, :raise end end end 

我常用的方法来看看它使用的SQL是在SQL中引入一个“错误”,然后你会得到一个错误消息吐出到正常的logging器(和网页屏幕),有问题的SQL。 没有必要find标准输出的地方

在Rails 3中,您可以将此行添加到config / environments / development.rb

 config.active_record.logger = Logger.new(STDOUT) 

它会执行查询。 但是有一半人回答: