ActiveRecord采用SQL

时间:2017-08-28 19:56:10

标签: ruby-on-rails activerecord rails-activerecord

我知道这两个语句执行相同的SQL:

使用select

User.select(:email)
# SELECT  `users`.`email` FROM `users`

使用pluck

User.all.pluck(:email)
# SELECT `users`.`email` FROM `users`

现在我需要获取从每个方法派生的SQL语句。鉴于select方法返回ActiveRecord::Relation,我可以调用to_sql方法。但是,我无法弄清楚如何获取从ActiveRecord::Relation对象上的pluck操作派生的SQL语句,因为结果是一个数组。

请注意,这是问题的简化。拔出的属性数量可以任意高。

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:9)

无法链接to_sql pluck,因为不会返回 ActiveRecord::relation。如果你尝试这样做,它会抛出一个像这样的异常

NoMethodError: undefined method `to_sql' for [[""]]:Array
  

我无法弄清楚如何获取从pluck派生的SQL语句   在给定结果的情况下对ActiveRecord :: Relation对象进行操作   是一个数组。

好吧,正如 @cschroed 在评论中指出的那样,他们(selectpluck)执行相同的SQL查询。唯一的区别是pluck返回array而不是ActiveRecord::Relation无关紧要您尝试提取多少属性,SQL语句将与select

相同

示例:

User.select(:first_name,:email)
#=> SELECT "users"."first_name", "users"."email" FROM "users"

同样适用于pluck

User.all.pluck(:first_name,:email)
#=> SELECT "users"."first_name", "users"."email" FROM "users"

因此,您只需要获取select返回的SQL语句,并认为它与pluck相同。就是这样!

答案 1 :(得分:2)

您可以对ActiveRecord::LogSubscriber类进行修补,并提供一个可以注册任何活动记录查询的单例,甚至是那些不返回ActiveRecord::Relation个对象的查询:

class QueriesRegister
  include Singleton
  def queries
    @queries ||= []
  end

  def flush
    @queries = []
  end
end

module ActiveRecord
 class LogSubscriber < ActiveSupport::LogSubscriber

  def sql(event)
    QueriesRegister.instance.queries << event.payload[:sql]
    "#{event.payload[:name]} (#{event.duration}) #{event.payload[:sql]}"    
  end
 end
end

运行查询:

User.all.pluck(:email)

然后,检索查询:

QueriesRegister.instance.queries