平均值范围
Scope on average value
我正在尝试在我的电影模型上定义一个范围,以便 select 所有平均评分高于所提供值的电影。
到目前为止我有以下型号:
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 中的查询选项。
我想要做的是有一个 select 特定电影的所有评级的范围。使用评级的 值 属性 计算平均值。如果该值等于或高于提供的值,则该电影是 selected.
在代码中我一直在玩 joins 和 average 查询选项,但我不确定如何将它们结合起来得到我想要的。
我想我找到了...
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 来测试它是否有效。
我正在尝试在我的电影模型上定义一个范围,以便 select 所有平均评分高于所提供值的电影。
到目前为止我有以下型号:
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 中的查询选项。 我想要做的是有一个 select 特定电影的所有评级的范围。使用评级的 值 属性 计算平均值。如果该值等于或高于提供的值,则该电影是 selected.
在代码中我一直在玩 joins 和 average 查询选项,但我不确定如何将它们结合起来得到我想要的。
我想我找到了...
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 来测试它是否有效。