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

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

问题描述:

我很努力地理解group如何在Rails中工作。目前并没有真正出现任何好的教程要么...Rails + postgres:在has_many上使用Group查询通过

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_doctor。 A patient可以有许多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}

想法?谢谢!

+0

我想你需要在分组后选择你需要的字段。 – Alfie

如果我正确理解你的问题,你需要使用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,则这可能会稍微低效,所以如果这是您应用程序中的关键路径,那么您可能还会在某处使用includeshttp://apidock.com/rails/ActiveRecord/QueryMethods/includes)。

+0

你确定吗? API文档说它很可能获得一组记录。 http://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-group – max

+0

由AR返回的集合是一个一维数组,即使在您链接的文档中,有时在某些边缘情况下除外像'count'。你说过你想要一张主要医生的地图(比如红宝石,散列结构),以及一系列病人。 SQL'group'用于在编组之前将许多行编译为单个表示*;这不是你在这里所要求的,至少。 – Woahdae

+1

在我的答案中增加了示例输出,以便您可以看到它与AR文档的不同之处,以及它是否是您的意思。 – Woahdae