Rails Active Record,从has_many获取相关记录:通过与where子句的关系来记录

时间:2015-03-14 20:14:06

标签: mysql ruby-on-rails activerecord

我与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

如果预约的角色等于PI或G2,我如何让所有患者为某位医生服务?

我试过了Physician.find(50).appointments.where('role = ? or role = ?', 'PI', 'G2').patients

编辑:

我从上面得到了未定义的方法。我不应该能够获得通过的相关记录吗?在Physician.find(50).appointments.where('role = ? or role = ?', 'PI', 'G2')中应该有appointments方法,但没有。

1 个答案:

答案 0 :(得分:1)

由于您需要返回Patient对象,请从该模型开始。您想在约会和医生上添加WHERE子句,因此请加入这些关联。使用where的哈希表单来引用已连接的表。

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

<强>更新

考虑将范围添加到您可以重复使用的模型中:

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

然后你可以像这样把它们放在一起

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