2011-12-26 69 views
4

什麼是寫下面的代碼的Rails的3.1:的Rails 3.1 named_scope

named_scope :min_2_items_last_90_days, { 
    :include => { :orders => :order_items }, 
    :conditions => ['orders.created_at >= ?', 90.days.ago], 
    :group => 'people.id', 
    :having => 'COUNT(order_items.id) >= 2' 
    } 

回答

7

在寫它作爲

scope :min_2_items_last_90_days, where(...) 

語法正確,它可能(比如你原來的代碼)不挺你在想什麼做的。

在這兩種情況下,90.days.ago僅在加載類時評估一次,所以90天將始終在應用程序上次重新啓動前90天。如果您還沒有重新啓動應用10天,那麼您實際上正在查看過去100天內創建的內容。您將不會注意到這一點,因爲您的源代碼不斷重新加載(因此重新評估了90.days)。

相反,你應該做的

scope :min_2_items_last_90_days, lambda { where('orders.created_at >= ?', 90.days.ago).includes(...) ... } 

這確保了條件將得到重新評估每次使用範圍的時間。

2
scope :min_2_items_last_90_days, lambda { where('orders.created_at >= ?', 90.days.ago).includes(:orders => :order_items).group('people.id').having('COUNT(order_items.id) >= 2') } 

NB(因爲它很容易忘記):使用lambda保證條件,每次都重新評估範圍被稱爲(另請參閱docs on scope)。由於90.days.ago表達式 - 需要重新評估,因此每次當範圍被稱爲時,您最終都需要評估90.days.ago。沒有lambda表達式,將不會發生重新評估,並且僅在服務器啓動時評估(僅)表達式。