user11703419
user11703419

Reputation:

What's Best Practice For Multiple Types of Users in Ruby on Rails

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

Answers (2)

Marlin Pierce
Marlin Pierce

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

Rakesh
Rakesh

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

Related Questions