Ruby on rails 如何同时在两个级别上对关联属性进行排序?
我相信这是一个简单的ruby问题。在我的应用程序中,我有很多评论的产品模型。每次评审都有一个“总体”评分属性,该属性是一个整数 我想做的是根据产品总体评级的平均值展示前十名产品。我已经做到了这一点,但是,我还想通过二级聚合属性对具有相同总体评级的产品进行排序,即该产品有多少评论。现在,如果我有3种产品具有相同的平均总体评级,它们似乎是以随机顺序显示的 到目前为止,我的代码是: 控制器 产品模型 型号:Ruby on rails 如何同时在两个级别上对关联属性进行排序?,ruby-on-rails,Ruby On Rails,我相信这是一个简单的ruby问题。在我的应用程序中,我有很多评论的产品模型。每次评审都有一个“总体”评分属性,该属性是一个整数 我想做的是根据产品总体评级的平均值展示前十名产品。我已经做到了这一点,但是,我还想通过二级聚合属性对具有相同总体评级的产品进行排序,即该产品有多少评论。现在,如果我有3种产品具有相同的平均总体评级,它们似乎是以随机顺序显示的 到目前为止,我的代码是: 控制器 产品模型 型号: def self.get_best_products(number) self.joins
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个记录数组进行排序吗?如果我想先对总体评分进行优先级排序,然后根据评论数量对具有相同总体平均评分的产品进行排序,那该怎么办?好的,现在问题对我来说更清楚了,我会考虑一下,如果我不介意的话,我会更新它,谢谢你的帮助