我有三个表
hospital_bed
,patient
和condition
。
每张病床可容纳一名病人每个病人可以有多种情况,但条件也可以为空,以防还不知道
我基本上想要显示所有的病床和病人,然后在一个可折叠的下面显示病人的所有情况。
为此,我需要像这样连接这三个表:
HospitalBed.joins(:patient).joins('JOIN condition ON patient.id = condition.patient_id')
这样我就收到了所有的床位、病人和他们的病情,除了那些还没有列出病情的病人。
我怎样才能得到它们呢?我知道这会成功的
HospitalBed.joins(:patient).joins('JOIN conditions')
但是这样生成的行比需要的多。
编辑:我要得到所有床位和所有病人不管他们是否有疾病. 我所能返回的是有条件的患者,但我也想要那些没有(尚未)有条件的患者。
This but via the HospitalBed
Patient.left_joins(:conditions).merge(Condition.where.not(id: nil).or(Condition.where(id: nil)))
这里不需要SQL字符串。您只需要正确设置您的关联:
class HostipitalBed
belongs_to :patient
has_many :conditions, through: :patient
end
然后你需要弄清楚你所说的"How do I also get them?";
HostipitalBed.joins(:conditions) # Left inner join
HostipitalBed.left_joins(:conditions) # Left outer join
HostipitalBed.includes(:conditions) # Loads the conditions in a separate query to avoid n+1
HostipitalBed.eager_load(:conditions) # Loads the conditions in a single query to avoid n+1
joins
和left_joins
实际上都没有从连接表中选择任何东西。如果您想要显示您想要使用include/eager load来避免n+1查询问题。
当使用joins
和符号时,Ruby on Rails默认会执行INNER JOIN。这意味着只返回两边都有匹配记录的关系。
但是,当您希望JOIN返回其中一条记录不存在的关系时,则需要使用OUTER JOIN。对于这些情况,Ruby on Rails有left_outer_joins
。但不幸的是,您不能使用该方法,因为您将需要在嵌套关联上使用OUTER JOIN。
HospitalBed
.joins(:patient)
.joins('LEFT OUTER JOIN conditions ON patients.id = conditions.patient_id')
请注意,当手动编写连接语句时,您需要使用复数形式的实际表名,就像在数据库中那样。