Oliver Trampleasure
Oliver Trampleasure

Reputation: 3293

ActiveRecord .where of .join / has_one :through

I have three models - Patient, Location and Area.

Every patient belongs to a location, and locations belong to areas. Areas have a boolean value called inpatient.

I need to select the patients who belong to a location that in turn belongs to an area with the inpatient value set to true.

I have tried the following but none are working:

@inpatient = Area.joins(:locations).joins(:patients).where(inpatient: true).count
@inpatient = Patient.joins(:location).join(:area).where(area: {inpatient: true}) 
@inpatient = Patient.joins(:area).where(area: {inpatient: true}).all 
@inpatient = Patient.joins(:location).joins(:area).where(area: {inpatient: true}).count

Would appreciate some help! I imagine this is simple and that I'm getting something basic wrong... I've had a look at the other questions which are similar but have been unable to re-purpose the answers into anything that works.


MODELS

class Patient < ApplicationRecord

  belongs_to :location, optional: true
  has_one :area, through: :location

end

-

class Location < ApplicationRecord

  has_many :patients
  belongs_to :area, optional: false

end

-

class Area < ApplicationRecord

  has_many :locations
  has_many :patients, through: :locations

end

Upvotes: 2

Views: 63

Answers (2)

Vasilisa
Vasilisa

Reputation: 4640

You can use your associations, it should produce the same SQL query, but it is more simple and readable

@inpatient = Area.where(inpatient: true).patients

Upvotes: 0

Noah
Noah

Reputation: 570

You are close. You have to use the table names in the where statement, NOT the relation name. Also, you have to use areas within the locations argument. Try this:

@inpatient = Patient.joins(:location).joins(:area).where(locations: {areas: {inpatient: true}}) 

Upvotes: 3

Related Questions