我的应用程序是关于具有与电影相关的许多愿望的个人资料:
class Profile < ApplicationRecord
has_many :wishes, dependent: :destroy
has_many :movies, through: :wishes
end
class Wish < ApplicationRecord
belongs_to :profile
belongs_to :movie
end
class Movie < ApplicationRecord
has_many :wishes, dependent: :destroy
has_many :profiles, through: :wishes
end
我想返回ID为1,2和3的配置文件“希望”所有全部的电影。
我设法使用原始SQL(postgres)来获取此查询,但是我想学习如何使用ActiveRecord进行查询。
select movies.id
from movies
join wishes on wishes.movie_id = movies.id
join profiles on wishes.profile_id = profiles.id and profiles.id in (1,2,3)
group by movies.id
having count(*) = 3;
(我依赖count(*)= 3,因为我有一个唯一的索引,可以防止创建具有重复的profile_id-movie_id对的愿望,但是我愿意寻求更好的解决方案)
目前,我找到的最好的方法是:
profiles = Profile.find([1,2,3])
Wish.joins(:profile, :movie).where(profile: profiles).group(:movie_id).count.select { |_,v| v == 3 }
(另外,我将从Movie.joins开始AR查询,但我没有设法找到方法:-)
答案 0 :(得分:0)
由于belongs_to将外键放在wishs表中,因此您应该能够像这样查询它的个人资料:
Wish.where("profile_id IN (?)", [1,2,3]).includes(:movie).all.map{|w| w.movie}
这应该按这三个配置文件为您提供所有电影的阵列,并希望加载电影。
答案 1 :(得分:0)
由于我要从查询中获得的是电影的集合,因此ActiveRecord查询需要从电影开始。我所缺少的是我们可以在查询中指定表,例如where(profiles: {id: profiles_ids})
。
这是我正在寻找的查询。 (是的,使用count
听起来有些脆弱,但是替代方法是使用昂贵的SQL子查询。此外,我认为如果使用多列唯一索引是安全的。)
profiles_ids = [1,2,3]
Movie.joins(:profiles).where(profiles: {id: profiles_ids}).group(:id).having("COUNT(*) = ?", profiles_ids.size)