2012-10-25 59 views
4

我想使用子查詢用ActiveRecord就像這樣:ActiveRecord的選擇與參數綁定

User.select(
    'users.*, 
    (select sum(amount) 
     from subscriptions 
     where subscriptions.user_id = user.id 
     and created_at < ?) as amt)' 
).order('amt') 

然而,在倒數第二行,我有我無法弄清楚如何綁定的問題Time類參數,因爲ActiveRecord::Baseselect方法不接受多個參數(sql字符串)。我該怎麼辦?

回答

8

您可以使用ActiveRecord::Sanitization class methods之一。

這些混合成ActiveRecord::Base和幾乎所有的保護,因此它們被你的模型定義一個類的方法最容易訪問:

class User < ActiveRecord::Base 
    def self.select_with_args(sql, args) 
    query = sanitize_sql_array([sql, args].flatten) 
    select(query) 
    end 
end 

這也是值得尋找其他方式來獲取你的數據,並比較它們性能到子查詢方法。例如,您可以使用單獨的查詢獲取訂閱計數:

subs_by_user = Subscription.group(:user_id).where('created_at < ?', d).count() 
+1

這不會阻止在db適配器中使用準備好的語句緩存嗎?看起來像http://apidock.com/rails/ActiveRecord/Sanitization/ClassMethods/sanitize_sql_array只是將當前值插入到語句中。 – qix