如何使用latsrate gem按平均评级对记录进行排序?

时间:2013-04-18 12:05:14

标签: ruby-on-rails rubygems

我使用letrate gem评级https://github.com/muratguzel/letsrate
如何按平均评分对记录进行排序?
或者我必须从头开始写自己的评价?

1 个答案:

答案 0 :(得分:2)

可以使用Letsrate gem对评级进行排序,但由于存在错误,因此有点困难。例如,一个User的应用程序,对速度,引擎和价格的评分为Car

class Car < ActiveRecord::Base
  attr_accessible :name
  letsrate_rateable "speed", "engine", "price"
end

现在,您可以创建一些用户,汽车和评级。

user = User.create!(email: 'user@example.com', password: 'password', password_confirmation: 'password')
other = User.create!(email: 'other@example.com', password: 'password', password_confirmation: 'password')

camry = Car.create!(name: 'Camry')
mustang = Car.create!(name: 'Mustang')
ferrari = Car.create!(name: 'Ferrari')

camry.rate 2, user.id, 'speed'
camry.rate 3, user.id, 'engine'
camry.rate 5, user.id, 'price'
camry.rate 4, user.id
mustang.rate 3, user.id, 'speed'
mustang.rate 4, user.id, 'engine'
mustang.rate 3, user.id, 'price'
mustang.rate 3, user.id
ferrari.rate 5, user.id, 'speed'
ferrari.rate 5, user.id, 'engine'
ferrari.rate 1, user.id, 'price'
ferrari.rate 5, user.id

camry.rate 3, other.id, 'speed'
camry.rate 2, other.id, 'engine'
camry.rate 4, other.id, 'price'
camry.rate 5, other.id
mustang.rate 4, other.id, 'speed'
mustang.rate 3, other.id, 'engine'
mustang.rate 3, other.id, 'price'
mustang.rate 4, other.id
ferrari.rate 5, other.id, 'speed'
ferrari.rate 4, other.id, 'engine'
ferrari.rate 1, other.id, 'price'
ferrari.rate 4, other.id

通过加入rate_average_without_dimension关联,很容易根据整体评分进行排序,没有维度:

Car.joins(:rate_average_without_dimension).order('rating_caches.avg DESC')

您可以将其视为

scope :sorted_by_rating_without_dimension, joins(:rate_average_without_dimension).order('rating_caches.avg DESC')
scope :top_ten_without_dimension, sorted_by_rating_without_dimension.limit(10)

现在你可以列出“前10名”名单:

Car.top_ten_without_dimension

但是,如果您想要“十大发动机”或“最佳价值”列表怎么办?它应该像

一样简单
Car.joins(:engine_average).order('rating_caches.avg DESC')
Car.joins(:price_average).order('rating_caches.avg DESC')

但是,你会收到错误

ActiveRecord::ConfigurationError: Association named 'engine_average' was not found; perhaps you misspelled it

这是因为Letsrate创建了与字符串而不是符号的关联。要解决此问题,您可以将letsrate_rateable调用更改为以下内容:

DIMENSIONS = ["speed", "engine", "price"]
letsrate_rateable *DIMENSIONS

DIMENSIONS.each do |dimension|
  has_one :"#{dimension}_average", :as => :cacheable, :class_name => "RatingCache", :dependent => :destroy, :conditions => {:dimension => dimension.to_s}
end

(请注意:插值前面的"#{dimension}_average"

现在,您可以使用

Car.joins(:engine_average).order('rating_caches.avg DESC')

或作为范围,

scope :sorted_by_engine_rating, joins(:engine_average).order('rating_caches.avg DESC')
scope :top_ten_engines, sorted_by_engine_rating.limit(10)

我有submitted a pull request修复了这个错误。随意发表评论或给它一个+1以使其被接受。