Rails查找具有多个关联记录的记录

时间:2015-10-30 17:20:59

标签: ruby-on-rails activerecord

假设我有一个教师模型,通过class_listings,包括teacher_id和student_id,有很多学生:

class Teacher < ActiveRecord::Base
  has_many :class_listings
  has_many :students, through: :class_listings
end

class ClassListing < ActiveRecord::Base
  belongs_to :teacher
  belongs_to :student
end

class Student < ActiveRecord::Base
  has_many :class_listings
  has_many :teachers, through: :class_listings
end

并存在:

  • 有学生1的老师1
  • 有学生2的老师2
  • 有学生1和学生2的老师3

我如何查询有学生1和学生2的老师?

我已经尝试了

Teacher.joins(:class_listings).where(class_listings: {student_id: [1,2]})

但是返回有1或2名学生(即教师1,2和3)的教师,而不是具有1 2的学生(即教师3)的教师。

2 个答案:

答案 0 :(得分:3)

假设您的班级列表是uniq,您也可以这样做:

@Html.ActionLink("Edit", "Edit", new { id = Model.StudentID })

SQL是:

student_ids = [1, 2]
Teacher.where(
  id: Rel.select(:teacher_id).group(:teacher_id).where(student_id: student_ids)
    .having("count(student_id) = ?", student_ids.count)
)

PS:我使用的是SELECT "teachers".* FROM "teachers" WHERE "teachers"."id" IN ( SELECT "rels"."teacher_id" FROM "rels" WHERE "rels"."student_id" IN (1, 2) GROUP BY "rels"."teacher_id" HAVING count(student_id) = 2 ) 模型,而不是Rel,抱歉 PPS:我也喜欢@ histocrat的解决方案。

答案 1 :(得分:1)

这很尴尬。这是没有直接编写SQL的一种方法:

Teacher.where(id: ClassListing.where(student_id: 1).select(:teacher_id))
       .where(id: ClassListing.where(student_id: 2).select(:teacher_id))

它由多个where子句组成,但它实际上只会生成一个SQL查询,类似于Select * from teachers where id in (Select teacher_id from ClassListing where student_id = 1) AND id in (Select teacher_id from ClassListing where student_id = 2)