2017-08-28 46 views
9

我知道這兩個語句執行相同的SQL: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

你在tryi要做什麼? ['pluck'](https://github.com/rails/rails/blob/master/activerecord/lib/active_record/relation/calculations.rb#L177)與'select'使用相同的SQL查詢,但它使用['' cast_values'](https://github.com/rails/rails/blob/master/activerecord/lib/active_record/result.rb#L99)返回一個數組而不是'ActiveRecord :: Relation'。 – cschroed

+0

我正在構建一個基於用戶輸入的查詢,並且我想提供關於實際正在執行的查詢的反饋 – Bustikiller

回答

8

不能to_sqlpluck因爲它不返回ActiveRecord::relation。如果您嘗試這樣做,它拋出鑑於結果 像這樣

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

例外,我無法弄清楚如何從一個ActiveRecord :: Relation對象上採摘 操作得到的SQL語句,是一個數組。

嗯,@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。而已!

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 
+0

什麼時候'queries'數組將被清空? – Bustikiller

+0

呃...你需要用'#flush'方法來控制自己 –