Ruby on rails 如何同时在两个级别上对关联属性进行排序?

Ruby on rails 如何同时在两个级别上对关联属性进行排序?,ruby-on-rails,Ruby On Rails,我相信这是一个简单的ruby问题。在我的应用程序中,我有很多评论的产品模型。每次评审都有一个“总体”评分属性,该属性是一个整数 我想做的是根据产品总体评级的平均值展示前十名产品。我已经做到了这一点,但是,我还想通过二级聚合属性对具有相同总体评级的产品进行排序,即该产品有多少评论。现在,如果我有3种产品具有相同的平均总体评级,它们似乎是以随机顺序显示的 到目前为止,我的代码是: 控制器 产品模型 型号: def self.get_best_products(number) self.joins

我相信这是一个简单的ruby问题。在我的应用程序中,我有很多评论的产品模型。每次评审都有一个“总体”评分属性,该属性是一个整数

我想做的是根据产品总体评级的平均值展示前十名产品。我已经做到了这一点,但是,我还想通过二级聚合属性对具有相同总体评级的产品进行排序,即该产品有多少评论。现在,如果我有3种产品具有相同的平均总体评级,它们似乎是以随机顺序显示的

到目前为止,我的代码是:

控制器 产品模型 型号:

def self.get_best_products(number)
  self.joins{reviews}.order{'AVG(reviews.overall), COUNT(reviews)'}.limit(number)
end
但我得到了这个错误:

PGError: ERROR:  column "products.id" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: SELECT  "products".* FROM "products" INNER JOIN "reviews" ...
PGError: ERROR:  missing FROM-clause entry for table "product"
LINE 1: ...eviews"."product_id" = "products"."id" GROUP BY product.i...
顺便说一句,我使用squelgem来避免在模型中使用直接的SQL代码

----更新2

现在我将“组”部分添加到我的方法中,但仍然得到一个错误:

def self.get_best_products(number)
  self.joins{reviews}.group('product.id').order{'AVG(reviews.overall), COUNT(reviews)'}.limit(number)
end
我得到这个错误:

PGError: ERROR:  column "products.id" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: SELECT  "products".* FROM "products" INNER JOIN "reviews" ...
PGError: ERROR:  missing FROM-clause entry for table "product"
LINE 1: ...eviews"."product_id" = "products"."id" GROUP BY product.i...

product.rb

scope :best_products, (lambda do |number|
  joins(:reviews).order('AVG(reviews.overall), COUNT(reviews)').limit(number)
)
Product.best_products(10)
产品\u controller.rb

scope :best_products, (lambda do |number|
  joins(:reviews).order('AVG(reviews.overall), COUNT(reviews)').limit(number)
)
Product.best_products(10)

这确保了数据库中的一切都发生了,因此您不会得到不需要的记录。

如果我得到了它,下面是我的想法:

由于
products
有许多
reviews
reviews
有一个
total
属性,我会在products表中添加一个
reviews\u counter
列,该列将随着每次添加的评论而递增,通过这种方式,您将能够获得更高的db性能,因为您不必对所有
产品
进行计数,就可以获得最多的评论

现在您可以通过
reviews\u counter
获得订购的产品:

@best\u products=products.order(“reviews\u counter desc”)

接下来,您将获得由
总体订购的每种产品的
评论

<% for prod in @best_products %>
  <%= prod.reviews.order("overall desc") %> # can do all this or more in helper
<% end %>

#可以在helper中完成所有这些或更多操作
同样,通过这种方式排序,如果您有3个总体相同的评论,您可以再使用一个
order()
语句,并按
name
id
或任何您喜欢的方式对其排序,这样它们就不会以随机顺序显示

这只是我的想法,我最近开发了一款需要类似功能的应用程序,我们刚刚在模型中添加了一个counter_字段,这样做并不违法:)


p、 我不太清楚每个产品要显示多少条记录,所以只需添加
。例如,限制(5)
,以仅获取产品的前5条评论。

在数据库中进行排序不是更好吗?也就是说,使用
order
而不是
sort
。它应该是
products.id
而不是
product.id
。我的错。嗨,谢谢你的回答。我试着一字不差地实现它,也试着用我在问题更新中的方式实现它。两种方法都产生了相同的错误。我尝试了加入{reviews.outer},但也没有解决问题。你能告诉我出了什么问题吗?试着添加
.group('product.id')
如果你要使用
group
你还必须使用
select
。你能给我一个如何使用group和select的例子吗?但是如果我像这样对控制器代码添加一个限制,难道我不应该只通过评论数获得前n名的产品,然后根据总体评分对视图中的n个记录数组进行排序吗?如果我想先对总体评分进行优先级排序,然后根据评论数量对具有相同总体平均评分的产品进行排序,那该怎么办?好的,现在问题对我来说更清楚了,我会考虑一下,如果我不介意的话,我会更新它,谢谢你的帮助