【问题标题】:Scope on average value平均值范围
【发布时间】:2015-06-04 14:31:19
【问题描述】:

我正在尝试在我的电影模型上定义一个范围,以便选择平均评分高于提供值的所有电影。

到目前为止,我有以下模型:

class Movie < ActiveRecord::Base
  # Callbacks & Plugins

  # Associations
  has_and_belongs_to_many :categories
  has_many :ratings

  # Validations
  validates :name, presence: true, uniqueness: true
  validates :description, presence: true

  # Scopes
  scope :category, -> (category) { joins(:categories).where("categories.id = ?", category) }
  scope :searchable, -> (query) { where("name LIKE '%?%'", query) }
  scope :rating, -> (rating) { joins(:ratings).average("ratings.value")) }
end

class Rating < ActiveRecord::Base
  # Callback & plugins

  # Associations
  belongs_to :user
  belongs_to :movie, counter_cache: true

  # Validations
  validates :value, presence: true, numericality: { only_integer: true, greater_than_or_equal_to: 1, less_than_or_equal_to: 5 }
  validates :user, presence: true, uniqueness: { scope: :movie_id }
end

现在我正在使用 Rails 中的查询选项。 我想要做的是有一个范围来选择特定电影的所有评级。使用评级的 value 属性计算平均值。如果该值等于或高于提供的值,则选择该电影。

在代码中我一直在使用 joinsaverage 查询选项,但我不确定如何将它们结合起来获得我想要的。

【问题讨论】:

    标签: sql ruby-on-rails activerecord


    【解决方案1】:

    我想我找到了它......

    scope :rating, -> (rating) { joins(:ratings).group("movies.id").having("AVG(ratings.value) > ? OR AVG(ratings.value) = ?", rating, rating) }
    

    为我生成以下查询:

     Movie Load (1.9ms)  SELECT "movies".* FROM "movies" INNER JOIN "ratings" ON "ratings"."movie_id" = "movies"."id" GROUP BY movies.id HAVING AVG(ratings.value) > 1 OR AVG(ratings.value) = 1
    

    这就是我想要的。现在将使用一些 Rspec 对其进行测试,看看它是否有效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多