has_many通过关联where和select结果

时间:2019-06-01 00:29:24

标签: ruby-on-rails ruby ruby-on-rails-5

所以我正在尝试使用WHERE条件过滤结果,但是它不起作用。

class Physician < ApplicationRecord
  has_many :appointments
  has_many :patients, through: :appointments
 end

class Appointment < ApplicationRecord
  belongs_to :physician
  belongs_to :patient
 end

class Patient < ApplicationRecord
  has_many :appointments
  has_many :physicians, through: :appointments
end

而我在这里做的是:

patients = Patient.joins(:physicians).includes(:physicians).where(:appointments => {:sick => true })

但是,我得到的是以下内容:

"results": {
  "patient": {
    "id": 2,
    "patient_name": "Rob"
   },
   "physicians": [
    {
      "id": 4,
      "physicians_name":...
      "sick":false
    ... ,
    {
      "id": 7,
     "physicians_name":...
     "sick":true
     ... 
     ... ,
      {
      "id": 7,
      "physicians_name":...
      "sick":false
     ... 
     ]
    }

因此,正如您所注意到的,我并不是只让病态为true的医生。有什么建议吗?

更新: 这是我的序列化器

class PatientSerializer < ActiveModel::Serializer
  attributes :records

 def records
    { info: records_info }
 end

 def records_info
  object.appointments.map do |a|
  a.attributes.merge(a.physician.attributes)
 end

结束 结束

2 个答案:

答案 0 :(得分:1)

我认为includes(:physicians)会导致加载异常,这会使where子句无法按预期工作。您能取出来看看是否可以解决吗?您可以将其粘贴在最后,看看是否也有帮助。

答案 1 :(得分:1)

由于sick属性存储在appointment上,因此您应该使用joins(:appointments)而不是joins(:physicians)

鉴于此,这应该返回您正在寻找的结果:

patients = Patient.joins(:appointments).includes(:physicians).where(appointments: { sick: true })

这样做的原因是where子句中的条件需要引用联接的表。由于physicians子句中未使用where表,因此不需要显式连接它;但是,appointments表确实需要显式联接。

includes(:physicians)允许“快速加载” physicians记录,这可以防止在访问序列化程序中的每个医师数据时将其变成N + 1查询。