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

时间:2016-04-23 11:58:08

标签: ruby-on-rails migration associations has-many-through rails-console

我是铁路的新手。我想通过与以下示例相关联来试用has_many。

  1. 有两种类型的医生。 operation_doctors和treatment_doctors。
  2. 有两种类型的患者。 operation_patients和treatment_patients。
  3. 关系: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.
    

1 个答案:

答案 0 :(得分:0)

patient.rb

class Patient < ActiveRecord::Base
  has_many :appointments

为此,您需要在约会表上添加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

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

单表继承

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

这是我数据模型的草图:

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

约会表将包含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,您可以对这些模型使用验证,以确保患者的类型正确。