2010-10-27 40 views
1

在我的應用程序中,我有三種模式:市場,交易和用戶。關係是非常簡單的:現在ActiveRecord在查詢中重複包含關聯?

class Market 
    has_many :users 
    has_many :deals 
end 

class User 
    belongs_to :market 
end 

class Deal 
    belongs_to :market 
end 

,爲了更方便地查詢其中的一些關係,市場模式連接到它的一些方法:

class Market 
    def revenue_by_date(date) 
    deal = self.deals.find(:all, :select => 'id, purchased, price', :conditions => ["start_time =?", date])[0] 
    i = 0 
    if deal && deal.isMade? 
     i = deal.purchased * deal.price 
    end 
    return i 
    end 

    def users_for_market 
    return self.users.count 
    end 
end 

所以,在我的控制,我需要收集有關所有市場的數據,然後我需要在各地進行深入研究。所以我有一個查詢,看起來像這樣:

markets = Market.find(:all, :order => :name, :include => [:users, :deals]) 

這將運行兩個包括查詢不如預期,但後來在我的代碼,我做這樣的事情:

markets.each do |m| 
    m.users_for_market 
    m.revenue_by_date(date_var) 
end 

它運行的各個查詢在那些模型方法中。我認爲:include應該取而代之嗎?

我可以做些什麼來減少我正在運行的查詢次數?

回答

1

:包括真棒,但如果你調用新的數據庫查詢,它不會阻止你。您可以減少DB打不過,通過改變你的市場方法:

class Market 
    def revenue_by_date(date) 
    deal = self.deals.select{|d| d.start_time == date}.first 

    i = 0 
    if deal && deal.isMade? 
     i = deal.purchased * deal.price 
    end 
    return i 
    end 

    def users_for_market 
    return self.users.size 
    end 
end 

讓我們落後的工作 - 在users_for_market,計數方法做了分貝查找,大小方法只檢查數組。在revenue_by_date中,我用一個ruby select方法取代了你的數據庫查詢,該方法遍歷這些項目,並只返回select塊等於「true」的那些。

Rails不會阻止您進行更多的數據庫查詢,但您可以輕鬆使用Ruby代碼來處理已經加載的內容。我希望這有幫助!

+0

users_for_market變化就像一個冠軍。儘管有關收入變化的快速問題:如果我還沒有運行查詢語句,會發生什麼?例如,我把這個方法稱爲一次性的。既然它需要一個數組,我可以在數組不存在的情況下使用if語句嗎? – 2010-10-27 18:08:14

+0

NM!想出了我自己的問題的答案。您的解決方案非常好 – 2010-10-27 18:15:47

+0

當然,沒問題!是的,如果你還沒有調用'find',那麼調用market.deals會自動完成。這可能是你想出來的,我只是想提到任何讀這個的人。 – 2010-10-27 18:22:41