Rails 关联 has_many 通过不使用多个模型

Rails association has_many through not working with multiple models

我是 rails 的新手。我想通过与以下示例的关联来尝试 has_many。

  1. 有两种类型的医生。 operation_doctors 和 treatment_doctors.
  2. 有两种类型的患者。 operation_patients 和 treatment_patients.

关系:Operation_doctors只能预约手术患者,反之亦然。同样适用于治疗医生。

Doctor.rb

class Doctor < ActiveRecord::Base
has_many :appointments
has_many :operation_patients, :class_name => 'Patient', :source => :operation_patient ,through: :appointments
has_many :treatment_patients, :class_name => 'Patient', :source => :treatment_patient ,through: :appointments
end

Patient.rb

class Patient < ActiveRecord::Base
has_many :appointments
has_many :operation_doctors,:class_name => 'Doctor', :source => :operation_doctor,through: :appointments
has_many :treatment_doctors,:class_name => 'Doctor', :source => :treatment_doctor,through: :appointments
end

Appointment.rb

class Appointment < ActiveRecord::Base
belongs_to :operation_doctor, :class_name => 'Doctor', :foreign_key => :operation_doctor
belongs_to :treatment_doctor, :class_name => 'Doctor', :foreign_key => :treatment_doctor
belongs_to :operation_patient, :class_name => 'Patient', :foreign_key => :operation_patient
belongs_to :treatment_patient, :class_name => 'Patient', :foreign_key => :treatment_patient
end

Rails 控制台出错: 输入:

@op1 = Patient.new
@od1 = Doctor.new 

错误:

irb(main):023:0> @op1.operation_doctors << @od1
(0.1ms)  begin transaction
(0.1ms)  rollback transaction
ActiveRecord::UnknownAttributeError: unknown attribute 'patient_id' for Appointment.

patient.rb

class Patient < ActiveRecord::Base
  has_many :appointments

为此,您需要在约会 table 上有一个 patient_id 字段。您的实际约会关系更为复杂。有两种解决错误的方法。

患者模型上的两次约会

class Patient < ActiveRecord::Base
  has_many :operation_appointments, :class_name => 'Appointment', :foreign_key => :operation_patient
  has_many :treatment_patients, :class_name => 'Appointment', :foreign_key => :treatment_patient

您需要为医生模型做同样的事情。

单一Table继承

我倾向于为这个解决方案制作一个更大的数据模型。既然你知道医生有两种类型,病人有两种类型,它们彼此不相容,并且它们有重复的逻辑,我会依靠继承。

这是我的数据模型的草图:

ActiveRecord::Base
 Doctor               Patient                 Appointment
  OperationDoctor      OperationPatient        OperationAppointment
  TreatmentDoctor      TreatmentPatient        TreatmentAppointment

约会 table 将包含 doctor_id、patient_id 和类型字段

rails g model appointment type:string patient:references doctor:references
rails g model operation_appointment --parent appointment

这将简化 类:

# appointment.rb
belongs_to :patient
belongs_to :doctor

# patient.rb
has_many :appointments
has_many :doctors, :through => :appointment

这样你的医生要么是 TreatmentDoctor 要么是 OperationDoctor,你可以对这些模型进行验证以确保患者的类型正确。