简体   繁体   English

Rails Active Record,从has_many:through关系中获取相关记录,并且where子句通过

[英]Rails Active Record, get related record from has_many :through relationship with where clause on through record

I have a relationship set up with a has_many :through . 我与has_many :through建立了关系。

class Physician < ActiveRecord::Base
  has_many :appointments
  has_many :patients, through: :appointments
end

class Appointment < ActiveRecord::Base
  belongs_to :physician
  belongs_to :patient

  # physician_id, patient_id
end


class Patient < ActiveRecord::Base
  has_many :appointments
  has_many :physicians, through: :appointments
end

How can I get all patients for a given physician where the appointment's role is equal to PI or G2? 在任命角色等于PI或G2的情况下,如何获得给定医师的所有患者?

I've tried Physician.find(50).appointments.where('role = ? or role = ?', 'PI', 'G2').patients 我已经尝试过Physician.find(50).appointments.where('role = ? or role = ?', 'PI', 'G2').patients

Edit: 编辑:

I'm getting undefined method from the above. 我从上面得到未定义的方法。 Shouldn't I be able to get the through's related records? 我是否应该能够获得通行证的相关记录? In Physician.find(50).appointments.where('role = ? or role = ?', 'PI', 'G2') there should be an appointments method but there is not. Physician.find(50).appointments.where('role = ? or role = ?', 'PI', 'G2') ,应该有一个appointments方法,但没有。

Since you want Patient objects back, start with that model. 由于您希望患者对象返回,因此从该模型开始。 You want to add WHERE clauses on both Appointments and Physicians, so join on those associations. 您想在约会和医师上都添加WHERE子句,因此请加入这些关联。 Use the Hash form of where to reference the joined tables. 使用哈希表形式在where引用联接的表。

Patient.joins(:physician).
  joins(:appointments).
  where(appointments: {role: ["PI", "G2"]}).
  where(physicians: {id: physician_id}).uniq

Update 更新

Consider adding scopes to your models that you can reuse: 考虑将范围添加到模型中以供重复使用:

class Patient < ActiveRecord::Base
  scope :for_physician, ->(physician_id) do
    joins(:physicians).
    where(physicians: {id: physician_id}
  end

  scope :for_roles, ->(roles) do
    joins(:appointments).
    merge(Appointment.for_roles(roles))
  end
end

class Appointment < ActiveRecord::Base
  scope :for_roles, ->(roles) do
    where(role: roles)
  end
end

Then you can put them together like this 然后你可以像这样把它们放在一起

Patient.for_physician(50).for_roles(["PI", "G2"]).uniq

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM