2009-11-19 122 views

回答

3

當檢索的產品,你可以這樣做:

@products = Product.find(:all, :include => :sales, :order => "sales.value DESC") 

'sales.value' 可以與任何價值,你試圖通過訂購來代替......


編輯:無視我答案的其餘部分。它不會以銷售價值降序返回產品對象,它將以銷售價值降序返回與產品關聯的銷售對象。 :P

此外,你可以在你的模型像指定排序:

Class Product 
     has_many :sales, :order => 'sale_value DESC' 
    end 

在「sale_value」是什麼你試圖通過訂購...和做這種方式,檢索該產品,你可以做:

@products = Product.all 
+0

@kchau在@ product.sales'將由'影響你的第二個例子':order'條款,但不'Product.all'頭仍需要指定它是這樣的:'Product.all(:包括=>:銷售)' – 2009-11-19 02:11:47

5

如果你想與他們有關的銷售數量,訂購的產品,它實際上是一種困難的問題,這取決於你的數據庫。谷歌搜索從transientink.com挖出一個答案,但這種解決方案不適合我個人。我懷疑這是因爲PostgreSQL處理GROUP BY子句與MySQL相比的差異。

另一種選擇是對Sales中的產品關聯啓用counter_cache(請參閱鏈接瞭解詳細信息)並按計數器緩存字段排序。

另一種選擇是使用Ruby進行排序:

@top_products = Product.find(:all, :include => :sales).sort_by { |p| p.sales.size } 

沒有與此兩個主要問題,第一個是,你利用你的網絡服務器來進行排序,這將減緩請求( )其次,你不能在查找器中使用:limit選項,所以如果你只想要銷售前10名的產品,你必須從數據庫中獲取所有的產品,在你的應用程序中對它們進行排序,然後限制它們。

15

通過在產品模型中使用計數器高速緩存列,您可能希望一石二鳥(另一隻鳥正在表演)。例如,假設您爲產品X進行銷售。當銷售被提交給數據庫時,它將運行回調以增加產品在數據庫行中的銷售數量。當你銷燬時,反而會減少產品的數量。

您需要在products表中設置一個緩存列。在新的遷移,做到這一點:

add_column :products, :sales_count, :integer, default => 0 

Product.reset_column_information 

Product.all.each do |product| 
    Product.update_counters(product.id, :sales_count => product.sales.length 
end 

你想也需要作出一些改變你的產品和銷售模式,是這樣的:

class Product < ActiveRecord::Base 
    has_many :sales 
end 

class Sale < ActiveRecord::Base 
    belongs_to :product, :counter_cache => true 
end 

然後,而不必裝載全部的銷售協會(在大型應用程序中,它們會變得詭計多端),您只需加載產品,然後您就可以獲得該行本身的關聯銷售數量,而這只是性能成本的一小部分。

希望這會有所幫助!

+0

真棒推薦:D – Ian 2011-08-17 01:39:30

+2

感謝您的提示。這裏的鏈接根據DOC:http://guides.rubyonrails.org/association_basics.html#belongs_to-counter_cache – user569825 2012-06-09 18:22:38

+1

某些生產系統可能會緩慢發現上面的遷移時,有超過10000條記錄等 對於SQL版本,你可以做類似 'UPDATE products SET sales_count =(SELECT COUNT(*)FROM sales WHERE sales.product_id = products.id)'(postgresql) – 2012-12-08 02:49:14