2009-07-19 115 views
1

让我们假设我有一个型号Category其中has_manyItems。现在,我想提供一个的表格,按照的各种属性排序的项目。例如,将顶部价格最高的产品分类。或根据其最佳评分项目对类别进行排序。或者根据最近的项目对类别进行排序(即,具有最近项目的类别将是第一个)。按子模型属性对ActiveRecord模型进行排序?

class Category < ActiveRecord::Base 
    has_many :items 

    # attributes: name 
end 

class Item < ActiveRecord::Base 
    belongs_to :category 

    # attributes: price, rating, date, 
end 

哪一个是最好的方法?

  1. 在类别模型上维护额外的列以保存用于排序的属性(即最高项目价格或该类别中项目的最佳评级)。我之前做过这件事,但它有点难看,并且需要每次更改商品时更新类别模型
  2. 订单条款中的一些神奇的SQL咒语?
  3. 还有别的吗?

我能想出的最好的就是这个SQL,用于生成按包含项目的最大价格排序的类别列表。

select categories.name, max(items.price) from categories join items group by categories.name 

不知道这是如何转化为Rails代码。如果我希望按最近项目的价格排序的类别,此SQL也不起作用。为了明显的性能原因,我确实试图将其保存在数据库中。

回答

0

这不正是什么:连接是为了什么?

Category.find(:all, :joins => :items, :order => 'price') 

Category.find(:all, :joins => :items, :order => 'rating') 
+0

这是朝着正确的方向,但我需要的不仅仅是一个简单的连接。我的部分解决方案是上面的,但我需要更多的灵活性,我不确定Rails代码。 – ideasasylum 2009-07-20 19:43:13

3

假设在项目模型中列出的属性是数据库列,可以做很多事情。

最简单的可能是named_scopes

/app/models/category.rb

class Category < ActiveRecord::Base 
    has_many :items 

    # attributes: name 
    named_scope :sorted_by_price, :joins => :items, :group => 'users.id', :order => "items.price DESC"  
    named_scope :sorted_by_rating, :joins => :items, :group => 'users.id', :order => "items.rating DESC" 

    named_scope :active, :condition => {:active => true} 


end 

然后,你可以只使用Category.sorted_by_price返回类别列表按价格排序,最高到最低。 named_scopes的优点使您可以链接多个相似的查询。使用上面的代码,如果你的类别有一个名为active的布尔值。您可以使用 Category.active.sorted_by_price获取按其最昂贵物品订购的活动类别列表。

相关问题