2013-06-23 35 views
2

我相信这是一个简单的红宝石问题。在我的应用程序中,我有has_many评论的产品模型。每个评论都有一个“整体”评分属性,它是一个整数。如何一次对两个级别的关联属性进行排序?

我想要做的是根据其总体评分的平均值显示前十位产品。我已经完成了这项工作,但是,我还想根据次要聚合属性对具有相同总体评级的产品进行排序,这将是多少人对该产品进行评估的结果。现在,如果我有3种产品具有相同的平均综合评分,它们似乎以随机顺序显示。

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

控制器

@best = Product.has_reviews.get_best_products(10) 

产品型号

scope :has_reviews, joins{reviews.outer}.where{reviews.id != nil} 

def self.get_best_products(number) 
    sorted = self.uniq 
    sorted = sorted.sort { |x, y| y.reviews.average("overall").to_f <=> x.reviews.average("overall").to_f } 
    sorted.first(number) 
end 

我已经试过这对我的模型代码:

def self.get_best_products(number) 
    sorted = self.uniq.sort! { |x, y| x.reviews.count.to_f <=> y.reviews.count.to_f } 
    sorted = sorted.sort { |x, y| y.reviews.average("overall").to_f <=> x.reviews.average("overall").to_f } 
    sorted.first(number) 
end 

..但它没有做到我想要的做。我只是在我的视图中遍历@best数组。

--- UPDATE

现在好了,我想这一点:

控制器:

@best = Product.get_best_products(6) 

型号:

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" ... 

我正在使用Squeel gem btw避免在模型中直接使用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: missing FROM-clause entry for table "product" 
LINE 1: ...eviews"."product_id" = "products"."id" GROUP BY product.i... 
+0

在数据库中进行排序不是更好吗?即使用'order'而不是'sort'。 – Mischa

+0

它应该是'products.id'而不是'product.id'。我的错。 – Arjan

回答

0

product.rb

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

products_controller.rb

Product.best_products(10) 

这可以确保一切都发生在数据库中,这样你就不会得到你不需要记录。

+0

嗨,谢谢你的回答。我试着逐字执行,也是我在更新我的问题时所采用的方式。两种方式都产生了相同的错误。我尝试加入{reviews.outer},但它也没有解决问题。你能告诉一下出了什么问题吗? – Zephyr4434

+0

尝试添加'.group('product.id')' – Arjan

+0

如果你打算使用'group',你还必须使用'select'。 – Mischa

0

如果我猜中了,这里是我的我会怎么做的想法:

由于products有许多reviewsreviewsoverall属性我想一个reviews_counter列添加到产品表,将与每个增量增加审查,这样你就可以获得更多的分贝性能,因为你不必count所有的products评论得到最多的审查。

现在你会得到的产品下令reviews_counter

@best_products = Products.order("reviews_counter desc")

和明年你会得到reviewsoverall订购的每件产品:

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

还订购这样,如果您有3条相同的总体评论,您可以再发一条order()陈述,并按nameidid排序你永远喜欢,所以他们不会随机显示。

这只是我的我会怎么做的想法,我最近在弄,需要类似的东西,我们只是增加了一个counter_field我们的模型一个应用程序,它不是非法这样做:)

附:对于我来说不是很清楚您想要为每个记录显示多少条记录,因此您只需添加.limit(5)即可获得产品的前5条评论。

+0

但是,如果我为这样的控制器代码添加一个限制,那么我是不是只能通过评论计数获得前n个产品,然后按总体评分对该视图中的n个记录进行排序?如果我想先优先考虑总体评分,然后仅对具有相同总体平均评分的评论数量进行排序,那该怎么办? – Zephyr4434

+0

对,现在这个问题对我来说更加清晰,我会考虑一下,如果可以的话,会更新它 – rmagnum2002

+0

谢谢,感谢帮助 – Zephyr4434

相关问题