我使用letrate gem评级https://github.com/muratguzel/letsrate
如何按平均评分对记录进行排序?
或者我必须从头开始写自己的评价?
答案 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以使其被接受。