0

MODELS

Patient:

Description:
Should have only 1 Referrer

Association:

has_and_belongs_to_many :referrer

Referrer:

Description:
Contains all the types of referrers such as, but is not limited to:

  • Partners
  • etc.

Association:

has_and_belongs_to_many :referrer

Referrer Type (a new model I think I should add):

Details of referrers are here, such as name of the website that lead the patient to go to this hospital, or name of the partner that suggested the hospital to the patient.




WORKFLOW & EXPLANATIONS

In a form, the hospital employee takes the details of the patient. One of the details is the referrer -- the entity that referred the patient to this hospital. The referrer is rendered as a dropdown listbox.

I made the association between Patient-Referrer as HABTM because of the following reasons:

  1. The Referrer model will also be used by another model aside from Patient.
  2. The Referrer model has its own scaffold where an admin can add/remove referrers.




REQUIREMENT (THE PROBLEM)

Every time the dropdown box's value is "Partner", there should be a field to input the name of that entity. That is where the 3rd model will come in. The 3rd model will contain the:

  1. name of the partner
  2. a reference to the Referrer model's record named "Partner"
  3. a reference to the Patient record.

With the 3rd model now in play, how will I be able to insert new referrer details for each patient per referrer, and making it cascadable, in a sense that when I delete the Patient, the Referrer detail will be deleted, but the Referrer will still be kept untouched, the rails way.

Community
  • 1
  • 1
SamuelDev
  • 1,112
  • 10
  • 14

1 Answers1

0

has_and_belongs_to_many is not so great

has_and_belongs_to_many (HABTM) is one the most limited relations in ActiveRecord and really only fits where you need a very simple many-to-many relationship and:

  • You will never need a join model or to attach logic to the join table
  • You will never need to attach any extra data to the join table
  • You will never need to query the join table separately

There is no HABTM "through" because HABTM does not have a join model. Thats kind of the whole point. You cannot use polymorphism in a HABTM relationship - as that requires a join model.

Using HABTM is not the correct choice here.

In most cases you should be using has_many :though instead.

Here what you want is a one to many relation with a join model:

class Patient < ActiveRecord::Base
  has_one :referral, dependent: :destroy
  has_one :referrer, through: :referral
end

class Referral < ActiveRecord::Base
  belongs_to :patient
  belongs_to :partner
  validates_uniqueness_of :patient_id
end

class Partner < ActiveRecord::Base
  has_many :referrals
  has_many :referred_patients, through: :referrals
end

Polymorpism

It is possible to use polymorphism to let the same associations point to different tables:

class Referral < ActiveRecord::Base
  belongs_to :referred, polymorphic: :true
  belongs_to :referrer, polymorphic: :true
  validates_uniqueness_of :referred_id, scope: :referred_type
end

You would need to add referred_type:string and referrer_type:string columns to referrals.

# app/models/concerns/referable.rb
module Referable
  extend ActiveSupport::Concern
  included do
    has_one :referral, as: :referred, dependent: :destroy
    has_one :referrer, through: :referral
    has_many :referrals, as: :referrer
    has_many :referred_entities, through: :referrals
                        source: :referred
  end
end

class Patient < ActiveRecord::Base
  include Referable
end

class Doctor < ActiveRecord::Base
  include Referable
end

class Partner < ActiveRecord::Base
  include Referable
end

This example would let Patient, Doctor and Partner be either the referring party or have a referral. However one big drawback is the lack of joins and eager loading for polymorphic associations since the joined table cannot be known beforehand.

max
  • 96,212
  • 14
  • 104
  • 165