简体   繁体   English

sort_by并不总是存在的值– ActiveRecord | 滑轨5

[英]sort_by a value that isn't always present – ActiveRecord | Rails 5

I'm working on a listing site that works with Location and Review models. 我正在一个与“ LocationReview模型配合使用的列表网站。 I was to be able to order the list of locations by their average rating calculated by any reviews that exist for the location. 我将能够根据位置的任何评论计算出的位置的平均评分来订购位置列表。

Location.all.sort_by(&:rating)

throws the error: 引发错误:

An ArgumentError occurred in search#search:

  comparison of BigDecimal with nil failed

Notice rating is a model method, not a field in the database, hence the use of sort_by . 通知rating是一种模型方法,而不是数据库中的字段,因此使用sort_by
How should I best modify to get this going? 我应该如何最好地进行修改以实现这一目标?
Any help would be much appreciated! 任何帮助将非常感激!

class Location < ApplicationRecord
  has_many :reviews

  def rating
    self.reviews.average('rating')
  end
end
class Review < ApplicationRecord
  belongs_to :location

  validates :title, presence: true
  validates :email, presence: true
  validates :rating, presence: true
  validates :comment, length: { maximum: 500 }
  validates :location, presence: true
end

To avoid having to overwrite your rating method (you might want it to return nil if there are no reviews), you can use the following: 为了避免覆盖rating方法(如果没有评论,您可能希望它返回nil ),可以使用以下方法:

Location.all.sort_by { |l| l.rating || 0 }

This will allow any location without a rating to fallback to a default of 0 in the ordering only if it's not got a rating. 这将允许没有分级的任何位置退却到的默认0 只有当它没有得到一个等级排序。

Then, for instance, you could still distinguish between locations with a genuine review score of 0 and those without any reviews. 然后,例如,您仍然可以区分真实评分为0和没有任何评论的位置。

If you're concerned about genuine scores of 0 clashing with those with not reviews, you can set the default lower, ie -1 . 如果您担心真实分数为0而不与未评价的分数发生冲突,则可以将默认分数设置为较低,即-1

For example, you might have somewhere you want to display review scores as follows: 例如,您可能需要在某处显示评论分数,如下所示:

= @location.rating || "Location has no reviews"

For example you can return 0 if no review are available: 例如,如果没有可用的评论,则可以返回0:

  def rating
    return 0 unless reviews.any?
    reviews.average(:rating)
  end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM