【问题标题】:MissingAttributeError when trying to order index based on average rating尝试根据平均评分订购索引时出现 MissingAttributeError
【发布时间】:2015-04-29 21:17:09
【问题描述】:

我正在尝试根据收视率的平均值订购指数。评级是评论模型上的整数属性。 以下是我的相关模型:

provider.rb

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

  def reviews
    Review.where("provider_id = ?", id)
  end
end

review.rb

class Review < ActiveRecord::Base
  belongs_to :user, foreign_key: 'user_id'
  belongs_to :provider, foreign_key: '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.tag %></td>
    <td><%= provider.description %></td>
    <td><%= provider.reviews.average(:rating) %></td>
  </tr>
<% end %>

导致此问题的代码(我认为)在我的产品控制器中:

providers_controller.rb

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

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

我无法访问视图中列出的任何属性。我不确定问题出在我的视图代码还是控制器代码上。谢谢你的帮助。

错误

activerecord (4.2.1) lib/active_record/attribute_methods/read.rb:93:in `block in _read_attribute'
activerecord (4.2.1) lib/active_record/attribute_set.rb:31:in `block in fetch_value'
activerecord (4.2.1) lib/active_record/attribute.rb:150:in `value'
activerecord (4.2.1) lib/active_record/attribute_set.rb:31:in `fetch_value'

错误编辑

显示 /home/Danae/RubymineProjects/canvas/app/views/providers/index.html.erb 其中第 20 行提出:

缺少属性:名称

解决方案 我的菜鸟错误。有一个干扰 avg_rating 的列名。 cschroed 的回答很完美。

【问题讨论】:

  • 你能发布整个错误,而不仅仅是“MissingAttributeError”吗?
  • 那会是完整的跟踪吗?
  • 通常是的。根据它的长度,您可能希望将其缩短为仅告诉您错误在哪里、行号等的最低级别的行。
  • 带跟踪的已编辑问题。
  • app/views/providers/index.html.erb:20:in block in _app_views_providers_index_html_erb___4343438652084474623_27379300'... 那一行的代码是什么?

标签: sql ruby-on-rails ruby-on-rails-4


【解决方案1】:

当您使用select("avg(reviews.rating) as avg_rating") 时,不会选择其他提供者列。如果您想选择其他列,您可以使用select("providers.*, avg(reviews.rating) as avg_rating"),然后因为avg 是一个聚合函数,您还必须使用group("providers.id")。试试:

@providers = Provider.select("providers.*, avg(reviews.rating) as avg_rating").joins(:reviews).group("providers.id").order("avg_rating DESC")

别名 avg_rating 应该是一个唯一的名称,与您的表中的任何列名都不匹配。

【讨论】:

  • 这并没有抛出错误,而是以与 Provider.all 相同的顺序呈现结果。有任何想法吗?非常感谢您的时间。
  • (1) 您的 Provider 上是否有 default_scope? (2) 在 Rails 控制台中,Provider.select("providers.*, avg(reviews.rating) as avg_rating").joins(:reviews).group("providers.id").order("avg_rating DESC").to_sql 显示什么? (3)Provider.select("providers.*, avg(reviews.rating) as avg_rating").joins(:reviews).group("providers.id").order("avg_rating DESC").map{ |p| p.avg_rating.to_f }显示什么?
  • 1) 没有默认范围。这是必要的吗? 2) "SELECT providers.*, 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\" GROUP BY providers.id ORDER BY avg_rating DESC" 3)
  • 3) Provider Load (0.6ms) SELECT providers.*, 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" GROUP BY providers.id ORDER BY avg_rating DESC => [4.333333333333333, 4.0, 5.0]
  • 有时默认范围会潜入ORDER 声明中,这是您不打算的,但这里不是这种情况。嗯,我不确定为什么没有正确订购。您使用的是哪个数据库?
猜你喜欢
  • 1970-01-01
  • 2021-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-06
  • 2021-12-08
相关资源
最近更新 更多