Morgan
Morgan

Reputation: 1449

Rails Database Schema: Sharing Records

I have users which have patients. But I'd like to be add the ability for users to share patients with one another. At the moment I'm creating at SharedPatient table with user_id indicating which user the patient has been shared with and patient_id indicating the patient. That works, but I have to get User.patients and then query the SharedPatient table for the ids of the other patients they have access to and then query the Patient table for their patient records.

I really just want to be able to call User.patients and retrieve both their shared patients and the ones they themselves created. A boolean indicating whether the user is the creator or not seems like a solid way to sort between them, but I'm worried it's a bit hacky. Is there a preferred way of going about this or an ActiveRecord relationship I'm overlooking?

edit

class User < ActiveRecord::Base
  has_many :patients
  has_many :notes
  has_many :shared_patients
end

class SharedPatient < ActiveRecord::Base
  belongs_to :user
  belongs_to :patient
end

class Patient < ActiveRecord::Base
  belongs_to :user
  has_many :recordings, dependent: :destroy
  has_many :notes, dependent: :destroy
  has_many :shared_patients, dependent: :destroy 
end

Upvotes: 0

Views: 122

Answers (2)

Coenwulf
Coenwulf

Reputation: 1937

I'd suggest adding a relationship model (could be named Contact, or something different, I'll use Contact below) between them. Then add a flag on that model that indicates that the user is the primary (or creator or whatever term you want) for that patient. Then you can add associations to tie them all together:

class User < ActiveRecord::Base
  has_many :contacts, dependent: :destroy
  has_many :patients, through: :contacts
end

class Patient < ActiveRecord::Base
  has_many :contacts, dependent: :destroy
  has_many :users, through: :contacts
end

class Contact < ActiveRecord::Base
  belongs_to :user
  belongs_to :patient
  # has a boolean attribute named primary
  scope :primary, -> { where(primary: true) }
end

Upvotes: 1

Ruby Racer
Ruby Racer

Reputation: 5740

For the first part of your question

patient.rb

class Patient < ActiveRecord::Base

:has_and_belongs_to_many :users, :through => :sharedpatients
...
end

user.rb

class User < ActiveRecord::Base

:has_and_belongs_to_many :patients, :through => :sharedpatients
...
end

sharedpatient.rb

class SharedPatient < ActiveRecord::Base
:belongs_to :user
:belongs_to :patient
...

end

So, for example, you will have:

@user=User.find(params[:id])
@[email protected]
@[email protected]

and so on, you get the picture.

For the second part, you should add an extra user_id field in your patients table, for instance, creator_id, which will hold the id of the user who created the patient. Then in you user.rb:

has_many :created_patients, :class_name =>  "Patient", :foreign_key => 'creator_id'

and in your patient.rb:

belongs_to :creator, :class_name =>  "User", :foreign_key => 'creator_id'

Then, you will have these methods:

user.created_patients #list of his own patients
patient.creator # who is the doctor who created him

Upvotes: 1

Related Questions