具有计数并具有ActiveRecord的多个联接

时间:2018-08-27 23:03:07

标签: ruby-on-rails activerecord rails-activerecord

我的应用程序是关于具有与电影相关的许多愿望的个人资料:

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查询,但我没有设法找到方法:-)

2 个答案:

答案 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)