My current project allows Doctors to have many Patients with which I can do the following:
dennis = Patient.create
frank = Doctor.create
dennis.update(doctor: frank)
dennis.doctor #=> frank
frank.patients #=> [dennis, ...]
But now I'd like to add a class Hospital, that can also have many patients. I don't want to just add another has_many to the Hostpital class because Patient 'ownership' may change again and eventually my patient model will be littered with foreign key fields, all but one of which will be empty. A polymorphic association appears to be just what I am looking for: a Patient can be 'owned' by either a Doctor or a Hospital:
class Patient < ActiveRecord::Base
belongs_to :owner, polymorphic: true
end
class Doctor < ActiveRecord::Base
has_many :patients, as: :owner
end
class Hospital < ActiveRecord::Base
has_many :patients, as: :owner
end
This allows us to do the following:
dennis = Patient.create
frank = Doctor.create
dennis.update(owner: frank)
dennis.owner #=> frank
frank.patients #=> [dennis, ...]
We cannot, however, call dennis.doctor to return frank. I understand that the owner may not always be an instance of the Doctor class, but much of my current code uses the #doctor and #doctor= methods. So I figured I could just define them:
class Patient < ActiveRecord::Base
belongs_to :owner, polymorphic: true
def patient=(patient)
self.owner_id = patient.id
self.owner_type = "Patient"
end
def patient
return nil unless self.owner
self.owner.class == Patient ? self.owner : nil
end
end
This seemed to work fine, however this association is still not reflected in my database. I have some custom SQL queries that reference patients.doctor. This now throws Mysql2::Error: Unknown column 'patients.doctor' with the polymorphic association.
Is there a better way I could be implementing this? At this point, going back through all of my code and sql queries to change .doctor to .owner would be prohibitively time consuming.
TL;DR Trying to switch from has_many to polymorphic association, but I'd like to keep the convenient getter and setter methods (as well as the associations in my database) provided by the has_many relationship.
Any help is appreciated!
ownerandowner=) like you describe. - Wizard of Ogz