【问题标题】:Ruby on Rails: Issue sorting index based on average review ratingRuby on Rails:基于平均评论评级的问题排序索引
【发布时间】:2015-07-06 09:52:18
【问题描述】:

因此,我尝试按平均评分对我的提供商(类似于用户)索引进行排序,最高的在顶部。它可以工作,但会为提供者拥有的每个评论添加一个额外的行。例如。如果我有一个提供 3 条评论的提供者,则该提供者将在提供者索引中显示 3 次。评分是评论上的一列,是 1-5 之间的整数。

provider.rb

class Provider < ActiveRecord::Base
  belongs_to :user, foreign_key: 'user_id', autosave: true
  has_many :reviews, dependent: :destroy
end

review.rb

class Review < ActiveRecord::Base
  belongs_to :user, foreign_key: 'user_id'
  belongs_to :provider, foreign_key: 'provider_id'
end

providers_controller.rb

class ProvidersController < ApplicationController
  before_action :set_provider, only: [:show, :edit, :update, :destroy]

 def index
   @providers = Provider.all
                 .joins(:reviews)
                 .order("reviews.rating DESC")
   @reviews = Review.find_by(params[:provider_id])
 end

index.html.erb

 <% @providers.each do |provider| %>
  <tr>
    <td><%= link_to provider.name, provider_path(provider.id) %></td>
    <td><%= provider.industry %></td>
    <td><%= provider.experience %></td>
    <td><%= provider.description %></td>
    <td><%= provider.reviews.average(:rating) %></td>
  </tr>
<% end %>

这可能真的很愚蠢,因为我对 Ruby + Rails 很陌生,但我似乎无法弄清楚/找到相关信息。我尝试将“AVG(reviews.rating) DESC”添加到 order 方法,但这给了我一个 SQLite 异常错误。

任何帮助将不胜感激!!!如果需要,很乐意提供更多信息。

【问题讨论】:

标签: ruby-on-rails sqlite postgresql ruby-on-rails-4


【解决方案1】:

它给了你一个 sql 错误,因为你的错误与 rails 无关。

在 SQL 中,如果您使用聚合函数(例如 avg()),则该列必须出现在您的 select 子句中。

Provider.select("avg(reviews.rating) as avg_rating").joins(:reviews).order("avg_rating desc")

由于下面的评论而编辑

【讨论】:

  • 感谢您的帮助!!当我尝试这个时,我得到 "SQLite3::SQLException: near "select": syntax error: SELECT select avg(reviews.rating) as avg_rating FROM "providers" INNER JOIN "users" ON "users"."id" = "providers "."user_id" INNER JOIN "reviews" ON "reviews"."user_id" = "users"."id" ORDER BY avg_rating desc"。我不确定 user_id 来自哪里?如果我尝试删除选择,我会收到提供者属性的缺失属性错误。有什么想法吗?
  • 做同样的事情,但将选择从字符串中拉出 rovider.select("avg(reviews.rating) as avg_rating").joins(:reviews).order("avg_rating desc")
  • 试过了,但在我看来,尝试访问 provider.name、provider.industry 等时出现缺少属性错误。我是否需要更改在视图中访问属性的方式?
【解决方案2】:

我假设您要询问同一提供商的多个结果,所以我将尝试解决这个问题。当您加入提供者和评论表时,您将为每个提供者返回与该提供者的评论一样多的行。这是因为如果我们有一个提供者: {:id => 1, :reviews => [...]} 并加入这些评论: [{:id => 1, :provider_id => 1, :content => "blah"}, {:id => 2, :provider_id => 1, :content => "bar"}, {:id => 3, :provider_id => 1, :content => "foo"}]

SQL 将返回一个类似于以下内容的表:

provider_id, review_id, content
1             1           blah
1             2           bar
1             3           foo

在您的情况下,我认为适当的解决方案就是完全消除连接子句。这样做应该可以消除重复,并且您仍然可以通过提供者的 has_many 关系访问评论。

【讨论】:

  • 这是有道理的,似乎正在发生的事情。但是,当我删除连接子句时,我没有得到这样的列:reviews.rating。因为我试图通过提供者reviews.rating 的平均值来排序结果,所以我需要在子句中使用average 函数,不是吗?感谢您的想法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-04-19
  • 1970-01-01
  • 1970-01-01
  • 2012-11-07
  • 2016-04-17
  • 1970-01-01
  • 2013-07-15
相关资源
最近更新 更多