Rails + postgres:在has_many上使用Group查询

时间:2016-04-28 14:37:22

标签: ruby-on-rails ruby postgresql ruby-on-rails-4 group-by

我正在努力理解group在Rails中的工作原理。似乎没有任何好的教程......

class Doctor
  has_many :appointments
  has_many :patients, through: :appointments
end

class Appointment
  has_many :doctors
  has_many :patients
end

class Patient
  has_many :appointments
  has_many :doctors, through: :appointments
end

Doctor类有一个字段primary_doctorpatient可以有多个doctors,但只有一个primary_doctor

鉴于具体的doctor,我想要一张医生看到的所有patients的列表,按primary_doctor为每个patient分组。

doctor.patients.joins(:appointments).where(appointments: { is_primary: true }).group("patients.id, appointments.doctor_id")

是我认为应该工作的,但这不会进行任何分组。如果我在末尾添加.count,它几​​乎可以提供我想要的内容,但不是实际的对象,而是获得{doctor_id=>patient_count}的哈希值。

思考?谢谢!

1 个答案:

答案 0 :(得分:2)

如果我理解你的问题,你需要使用Ruby的内存中group_by函数。除非我在过去10年中遗漏了一些内容,否则ActiveRecord无法直接将数据库查询编组到您正在寻找的表示类型中。

因此,要获得医生看到的所有患者的清单,按每个患者的primary_doctor分组,您可以这样做:

doctor.patients.joins(:appointments).where(appointments: { is_primary: true }).
  group_by(&:primary_doctor)

这会给你一个结果:

{
  <Doctor id: 1, name: "Dr Bob"> =>
    [<Patient id: 1, name: "Joe">,
     <Patient id: 2, name: "Jane">],
  <Doctor id: 2, name: "Dr Spock"> =>
    [<Patient id: 3, name: "Jack">,
     <Patient id: 4, name: "Jill">,
     <Patient id: 5, name: "Scotty">]
}

请注意,如果您每次都需要返回数据库以获取primary_doctor,这可能会效率低下,因此如果这是您应用中的关键路径,您可能还会使用includes({{3在那里的某个地方。