I have three tables.
hospital_bed
, patient
and condition
.
each hospital bed can have one patient
each patient can have many conditions, but conditions can also be null in case it is not known yet
I basically want to display all beds and patients and then in a collapsable underneath all the conditions of the patient.
For that, I need to join these three tables like this:
HospitalBed.joins(:patient).joins('JOIN condition ON patient.id = condition.patient_id')
This way I receive all beds and patients and their conditions except the patients that do not have a condition listed yet.
How do I also get them? I know this would work
HospitalBed.joins(:patient).joins('JOIN conditions')
But this generates way too many rows than necessary.
Edit:
I want to get all beds and all patients no matter if they have a condition or not. All I can return are patients that have conditions but I also want the ones that do not have one (yet).
This but via the HospitalBed
Patient.left_joins(:conditions).merge(Condition.where.not(id: nil).or(Condition.where(id: nil)))
2
Answers
Ruby on Rails will do an INNER JOIN per default when using
joins
with a symbol. That means only relations will be returned that have matching records on both sides.But when you want a JOIN to return also relations where one of the records does not exist, then you need to use an OUTER JOIN. Ruby on Rails has the
left_outer_joins
for those cases. But unfortunately you cannot use that method, because you will need the OUTER JOIN on a nested association.Therefore, in your case the best option seems to be the writing the JOIN statement yourself, like this:
Please note that when writing the join statement manually, then you need to use the real tables names in plural like they are named in the database.
You don’t need a SQL string here. You just need to setup your associations properly:
And then you need to figure out what you actually mean by "How do I also get them?":
Both
joins
andleft_joins
don’t actually select anything from the joined table. If you want to display the conditions you want to use include/eager load to avoid a n+1 query issue.