2011-11-22 52 views
8

有了這些機型:如何通過使用rails和mongoid關聯的「計數」來查找記錄?

class Week 
    has_many :proofs 
end 
class Proof 
    belongs_to :week 
end 

我想要做的事,如:

Week.where(:proof.count.gt => 0) 

要查找有多個證據只有幾個星期。

有一個答案似乎解決這個:

Can rails scopes filter on the number of associated classes for a given field

但在這個例子中,不存在這樣的屬性在周proof_ids因爲ID存儲與證明。這不起作用,例如:

Week.where(:proof_ids.gt => 0) 

此查詢的可能性如何?從概念上講很簡單,但我不知道如何用mongo或mongoid做到這一點。

同樣,我想通過樣張的數量,例如像命令:

Week.desc(:proofs.size) 

但這也不起作用。

我知道一個計數器緩存是一個選項,可以用於解決兩個具體問題,但我也希望能夠執行查詢。

在此先感謝您的幫助。

回答

5

隨着軌(並且沒有counter_cache),你可以這樣做:

class Week < ActiveRecord::Base 
    has_many :proofs 

    def self.by_proofs_size 
    sort_by { |week| week.proofs.size } 
    end 

    def self.with_at_least_n_proofs(n = 1) 
    select { |week| week.proofs.size >= n } 
    end 
end 

即使每個這些業務產生的2個查詢,這是很不理想。

該對查詢的重複(=> 4個查詢每個操作)範圍(錯誤):

​​

理想的可能是使用counter_cache

scope :with_at_least_n_proofs, -> (n = 1) { where('proofs_count >= ?', n) } 
scope :by_proofs_size, -> { order(proofs_count: :desc) } 
+0

您可以刪除包含(:校樣)以提高性能一噸。目前,當您真正需要的是快速計數查詢時,您將加載所有數據:校樣。試試看。 –

+0

@RobVolk這是一些舊的代碼!感謝您的領導! – Damien

+0

它會殺了你的應用程序,因爲你將收到所有的證據從數據庫到你的應用程序的所有證據 – antiqe

0

對不起,如果我走了 - 但你能在周表中使用簡單的counter_cache嗎?然後你可以做一些像week.proofs_count。

+0

是的,正如我在我的問題中所說的,我知道counter_cache是​​一個選項,但如果可能的話,我寧願在這種情況下執行查詢。如果這不起作用,那麼我一定會做計數器緩存。 – eagspoo

4

我不不知道這是否是最好的解決方案,因爲它通過一個陣列來映射它,但是這樣做的工作:(這裏提到的其他解決方案給我例外)

class Week < ActiveRecord::Base 

    scope :has_proofs, -> { any_in(:_id => includes(:proofs).select{ |w| w.proofs.size > 0 }.map{ |r| r.id }) } 

end 
相關問題