2011-12-14 93 views
15

我有一個ActiveAdmin索引頁預先加載相關模型

ActiveAdmin.register Bill 

,我試圖以顯示指向關聯模型

index do 
    column "User" do |bill| 
    link_to bill.user.name, admin_user_path(bill.user) 
    end 
end 

但我碰上了N + 1查詢問題 - 有一個查詢來獲取每個用戶。

有沒有方法急於加載賬單的用戶?

回答

26

有在不同的帖子上回答,但它很好地描述了你需要在這裏做什麼。

controller do 
    def scoped_collection 
     Bill.includes(:user) 
    end 
    end 

在這裏,您需要確保遵循範圍。因此,如果您的控制器是scope_to'ed,那麼您將需要用scope_to'ed參數替換上面的模型名稱。

1

重要編輯注:接下來居然是假,看到一個解釋的意見。但是我留下這個答案,因爲看起來我不是唯一一個被導遊弄糊塗的人,所以也許別人會覺得它很有用。

我認爲

class Bill < ActiveRecord::Base 
    belongs_to :user 
end 

所以according to RoR guides已經是躍躍欲試加載:

有沒有必要使用:包括直接的關聯 - 也就是 如果你有訂單belongs_to的:客戶,那麼當需要時,客戶自動加載 。

你應該檢查你的SQL日誌,如果它是真實的(不知道我自己,我只是驗證一些有關:include回答你當我看到這個...讓我知道)

+0

官方文件中指出,我認爲這是很值得懷疑,但誰知道? – 2011-12-14 23:20:38

+2

_客戶在需要時自動加載 - 這意味着,如果您有1000個訂單並遍歷它們,則調用`order1.customer`,並且'customer1`因爲需要而被加載。然後你訪問`order2.customer`,但是,你沒有說你會需要它,所以對數據庫的另一個查詢就完成了。但是它仍然不知道在下一次迭代中你需要`customer3`,所以你會得到1000個查詢,而不是1. – RocketR 2012-03-16 16:29:45

+0

謝謝你的清除。我發現這種方式讓事情變得混亂,但英語不是我的母語。 – 2012-03-19 09:48:18

10

執行此操作的方法是覆蓋scoped_collection方法(如Jeff Ancel的答案中所述),但請撥super以保留現有範圍。這樣您就可以保留ActiveAdmin應用的現有範圍和任何分頁/過濾,而不是從頭開始。

ActiveAdmin.register Bill do 
    controller do 
    def scoped_collection 
     super.includes :user 
    end 
    end 

    index do 
    column "User" do |bill| 
    link_to bill.user.name, admin_user_path(bill.user) 
    end 
    end 
end 

截至http://activeadmin.info/docs/2-resource-customization.html