Reputation:
I'm building an application that has multiple types of users. Think: patient and doctor.
A patient has many doctors, and a doctor has many patients.
Initially I was going to put them all under one user, and maybe add a role column, or was considering polymorphic referencing(which I'm not so familiar with yet).
Is it better to do the above, or is it better to simply have them as different Classes. The problem I'm trying to resolve starts with logging in, and then class relations with the join table. For example, How can a User have many Users through Appointments? Is that possible?
What's the best practice for what I'm going for here?
Upvotes: 1
Views: 658
Reputation: 10079
If patients have many doctors and doctors have many patients, then you have a many-to-many relationship. A many-to-many relationship requires a linking table.
Let's call this a "treatments" relationship, (because I don't have a good name for it, it should be a noun) as a doctor treats a patient. Your migration would be
create_table :treatments do |table|
table.timestamps
table.integer :doctor_id
table.integer :patient_id
end
Then your associations would have to specify that these ids go to the users
table.
class Treatment < ApplicationRecord
belongs_to :doctor, class_name: 'User'
belongs_to :patient, class_name: 'User'
end
class User < ApplicationRecord
has_many :as_patient_treatments, class_name: 'Treatment', foreign_key: patient_id
has_many :doctors, through: :as_patient_treatments
has_many :as_doctor_treatments, class_name: 'Treatment', foreign_key: doctor_id
has_many :patients, through: :as_doctor_treatments
end
You may want to break this out using STI, if you have more behavior which differs between doctor and patient.
class User < ApplicationRecord
end
class Patient < User
has_many :as_patient_treatments, class_name: 'Treatment', foreign_key: patient_id
has_many :doctors, through: :as_patient_treatments
end
class Doctor < User
has_many :as_doctor_treatments, class_name: 'Treatment', foreign_key: doctor_id
has_many :patients, through: :as_doctor_treatments
end
Another, entirely legitimate approach, especially if you have additional data for patients and doctors, is to have a doctors
, a patients
, and a users
table, instead of STI. You still need the treatments
table to link doctors and patients.
The meaning of User
is an account which can log in. A doctor and a patient can have a user_id
to their login account.
create_table :users do |table|
table.timestamps
table.string :username
table.string :email
...
end
create_table :doctors do |table|
table.timestamps
table.bigint :user_id
table.specialty
...
end
create_table :doctors do |table|
table.timestamps
table.bigint :user_id
table.payer
...
end
create_table :treatments do |table|
table.timestamps
table.bigint :doctor_id
table.bigint :patient_id
end
class User
has_one :doctor
has_one :patient
...
end
class Treatment
belongs_to :doctor
belongs_to :patient
end
class Doctor
belongs_to :user
has_many :treatments
has_many :patients, through: :treatments
delegate :username, :email, :to => :user
...
end
class Patient
belongs_to :user
has_many :treatments
has_many :doctors, through: :treatments
delegate :username, :email, :to => :user
...
end
Upvotes: 0
Reputation: 841
You can Single table inheritance over here.
class User
end
class Patient < User
end
class Doctor < User
end
In users table you will have type column which will decide what type of the user it is.
reference - https://medium.com/@dcordz/single-table-inheritance-using-rails-5-02-6738bdd5101a
Upvotes: 1