我知道这两个语句执行相同的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语句,因为结果是一个数组。
请注意,这是问题的简化。拔出的属性数量可以任意高。
任何帮助都将不胜感激。
答案 0 :(得分:9)
你无法链接to_sql
pluck
,因为不会返回 ActiveRecord::relation
。如果你尝试这样做,它会抛出一个像这样的异常
NoMethodError: undefined method `to_sql' for [[""]]:Array
我无法弄清楚如何获取从pluck派生的SQL语句 在给定结果的情况下对ActiveRecord :: Relation对象进行操作 是一个数组。
好吧,正如 @cschroed 在评论中指出的那样,他们(select
和pluck
)执行相同的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