2010-05-12 63 views
2

我有一個頁面需要很長時間才能渲染出來。一半的時間(3秒)花費在一個具有一堆急切加載的關聯的.find調用上。我實際需要的是每種情況下關聯記錄的數量,以顯示在表格中:我不需要實際的記錄本身。有沒有辦法只是急於加載計數?這裏有一個簡單的例子:Rails - 急於加載相關記錄的數量,但不是記錄本身

@subjects = Subject.find(:all, :include => [:questions]) 

在我的表,每行(即每個科目)我只顯示主題字段的值和每個主題相關的問題的數量。我可以優化上述查找電話以適應這些要求嗎?

我想過使用group字段,但我的完整調用包含幾個不同的關聯,包含一些二階關聯,所以我不認爲group by會起作用。

@subjects = Subject.find(:all, :include => [{:questions => :tags}, {:quizzes => :tags}], :order => "subjects.name") 

:標記在這種情況下是通過標記的二階關聯。如果不清楚發生了什麼,這是我的協會。

Subject 
    has_many :questions 
    has_many :quizzes 

Question 
    belongs_to :subject 
    has_many :taggings 
    has_many :tags, :through => :taggings 

Quiz 
    belongs_to :subject 
    has_many :taggings 
    has_many :tags, :through => :taggings 

感謝您的任何意見 - 最大

回答

1

您可以實現此目的的計數器緩存。我在相冊模型上保留了一個計數器,用於跟蹤與其關聯的照片數量。我的過程看起來有點像這樣(我相信我發現了一個博客某處這種方法,所以,我要爲原代碼沒有信用):

在照片模式:

after_save :update_counter_caches 
after_destroy :update_counter_caches 

def update_counter_caches 
    self.albums.each { |a| a.update_count } unless self.albums.empty? 
end 

在相冊模式:

def update_count 
    update_attribute(:photographs_count, self.photographs.length) 
end 

你需要對專輯的遷移:

class AddCounterCacheColumnToModels < ActiveRecord::Migration 
    def self.up 
    add_column :albums, :photographs_count, :integer, :default => 0 
    end 

    def self.down 
    remove_column :albums, :photographs_count 
    end 
end 

,我就必須誤解了你的問題,這應該是一個非常簡單的方式來實現你想要的。它適用於我目前的項目。 :)


編輯:作爲一個說明,我用這個設置,而不是默認的原因:counter_cache方法,因爲我需要保持在一個模型多個關聯多個計數器。據我所知,你不能通過:counter_cache來達到目的。

0

最快的方式,我認爲:

@subjects = Subject.count(:joins => :questions, :select => 'DISTINCT(questions.id)') 

而且我不知道對於更復雜的查詢(未測試):

@subjects = Subject.count(:joins => [{:questions => :tags}, {:quizzes => :tags}], :select => 'DISTINCT(tags.id)' 
+0

由於地板 - 這是不是完全是我要求的,但。我希望主題的所有領域和每個主題的相關問題的數量。這只是列出了所有主題彙總在一起的相關問題的總數(與所有問題都有一個主題的問題中的計數(*)相同)。 – 2010-05-13 08:50:12

+0

完全沒有問題,它會返回已獲得主題的問題的計數(在這種情況下實際情況相同,但可以將其與計數標籤一起使用) – fl00r 2010-05-13 10:02:52

3

我認爲最好是在belongs_to協會使用:counter_cache

class Subject < ActiveRecord::Base 
    has_many :questions 
end 

class Question < ActiveRecord::Base 
    belongs_to :subject, :counter_cache => true 
end 

要使用counter_cache,你還需要一個questions_count列添加到您的subjects表。

railsapi.com

:counter_cache
緩存通過increment_counter和 decrement_counter的使用 的關聯類屬於對象 的數量。創建並遞減,當這個 類的一個對象時 它破壞了計數器緩存 遞增[...]

+0

執行此操作。這是比其他兩個更好的解決方案。 – kikito 2010-05-12 13:14:07

+0

謝謝 - 在這種情況下,計數器緩存很好,因爲它發生了,我已經去了。儘管如此,我仍然有興趣回答我的原始問題。 – 2010-05-13 08:47:08