3

我有一個小的rails應用程序,我試圖獲得一些訂單統計。 所以我有一個管理模型和一個訂單模型,一對多關聯。ActiveRecord:包括 - 如何使用加載關聯的地圖?

class Admin < ActiveRecord::Base 
    attr_accessible :name 
    has_many :orders 
class Order < ActiveRecord::Base 
    attr_accessible :operation 
    belongs_to :admin 

我試圖用這個查詢以獲得特異性目的訂單:

admins = Admin.where(...).includes(:orders).where('orders.operation = ?', 'new gifts!') 

按預期工作而已。但是當我嘗試使用這樣的地圖製作json時,使用新查詢再次加載訂單,而忽略已加載的對象。

(5.6ms) SELECT "orders"."operation" FROM "orders" WHERE "orders"."admin_id" = 26 
(6.8ms) SELECT "orders"."operation" FROM "orders" WHERE "orders"."admin_id" = 24 
(2.9ms) SELECT "orders"."operation" FROM "orders" WHERE "orders"."admin_id" = 30 
(3.3ms) SELECT "orders"."operation" FROM "orders" WHERE "orders"."admin_id" = 29 
(4.8ms) SELECT "orders"."operation" FROM "orders" WHERE "orders"."admin_id" = 27 
(3.3ms) SELECT "orders"."operation" FROM "orders" WHERE "orders"."admin_id" = 28 
(5.1ms) SELECT "orders"."operation" FROM "orders" WHERE "orders"."admin_id" = 25 

當我嘗試使用 循環,而不是地圖,它的作品,因爲它應該:

admins.each do |a| 
    p a.orders.pluck(:operation) 
end 

這個代碼不加載所有的訂單,而且只打印那些在第一個查詢加載。 使用map可以得到相同的結果嗎?使用循環代替map的缺點是什麼?

+0

什麼是您的Ruby和Rails版本? – tihom

+0

在使用關聯條件時,我最好使用Ruby 1.9.3和Rails 3.2 –

+1

作爲一般規則,最好使用'joins'。看到這[回答](http://stackoverflow.com/questions/14470027/activerecord-cant-use-pluck-after-where-clause-with-eager-loaded-associati)。雖然問題依然存在,爲什麼它在'each'而不是'map'中工作, – tihom

回答

6

pluck應始終對數據庫進行新的查詢。不知道爲什麼你認爲這不會發生在each循環。也許你沒有看到日誌,因爲它在你的印刷品之間?

如何避免附加查詢有兩種可能性。

  1. 既然已經加載訂單,因爲你有他們,你可以做admins.map {|a| [a.name, a.orders.collect(&:operation)]}

  2. 使用連接(見@ tihom的評論)。

編輯:我只是測試了each/map行爲,並重新加載每次按預期時間。

+0

好吧,我用.count代替了.pluck,得到了與我的問題相同的結果,所以我相信事實並非如此。 –

+1

count的行爲方式相同,所有ActiveRecord :: Calculations方法(count,average,minimum,maximum,calculate,sum pluck和ids)都會執行新的查詢,而不管內容是否加載。你不必接受我的話,你可以自己看看Rails代碼。 – mechanicalfish