1

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

4

1 回答 1

2

可以使用 Letsrate gem 按评分排序,但由于一个错误,这有点困难。举个例子,一个带有Users的应用程序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)

我已提交修复此错误的拉取请求。随意发表评论或给它+1以使其被接受。

于 2013-04-18T16:50:03.867 回答