【问题标题】:How do I get the last SQL query performed by ActiveRecord in Ruby on Rails?如何在 Ruby on Rails 中获取 ActiveRecord 执行的最后一个 SQL 查询?
【发布时间】:2009-07-07 07:17:33
【问题描述】:

我正在寻找类似 CodeIgniter 的东西:

$this->db->last_query();

(http://codeigniter.com/user_guide/database/helpers.html)

【问题讨论】:

  • 你想做什么?我认为这并不简单——您可能必须在某处修改 ActiveRecord。我还担心这样的操作会破坏(诚然泄漏的)抽象。可能有更好、更适合 Rails 的方式来实现您想要做的事情。
  • 我想在 Rails/ActiveRecord 日志级别设置为低时记录查询,所以我只会看到我真正感兴趣的查询。

标签: ruby-on-rails ruby activerecord


【解决方案1】:

AFAIK,没有简单的方法可以访问查询列表。尽管如此,您还是可以轻松访问它们,创建一个超级简单的记录器。

如果你打开 ActiveRecord::ConnectionAdapters::AbstractAdapter 类,你会看到一个名为 log 的方法。在每个查询上调用此方法以记录语句。默认情况下,它使用 Rails 记录器记录所有语句。

你可以这样做

ActiveRecord::ConnectionAdapters::AbstractAdapter.class_eval do

  attr_reader :last_query
  alias_method_chain :log, :last_query

  def log_with_last_query(sql, name, &block)
    @last_query = [sql, name]
    log_without_last_query(sql, name, &block)
  end

end

现在您可以使用

获取查询
ActiveRecord::Base.connection.last_query # => ...

【讨论】:

  • +1 用于猴子修补 Rails 的一部分,猴子修补之王。
  • 我必须在方法定义之后调用alias_method_chain,否则会导致以下错误:core_ext/module/aliasing.rb:32:in 'alias_method': undefined method 'log_with_last_query' for class 'ActiveRecord::ConnectionAdapters::AbstractAdapter' (NameError)
【解决方案2】:

可能是因为我的 ActiveRecord 版本比问这个问题时更新,但为了让它与 ActiveRecord 3.2.3 一起使用,我更新了 Simone Carletti 的脚本:我添加了额外的属性 binds 并移动了调用到方法定义下方的alias_method_chain,否则会引发错误,提示找不到方法。

ActiveRecord::ConnectionAdapters::AbstractAdapter.class_eval do

  attr_reader :last_query

  def log_with_last_query(sql, name, binds=[], &block)
    @last_query = [sql, name]
    log_without_last_query(sql, name, binds, &block)
  end
  alias_method_chain :log, :last_query

end

获取最后一个查询还是一样:

ActiveRecord::Base.connection.last_query # => ...

【讨论】:

    【解决方案3】:

    您的开发日志应包含所有运行的 SQL 查询。

    【讨论】:

    • 是的,但就是这样——它有所有的查询。我只想查看我明确记录的内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-23
    • 1970-01-01
    • 2014-04-28
    • 2012-12-16
    • 1970-01-01
    • 2011-04-11
    相关资源
    最近更新 更多