Foosaurus
Foosaurus

Reputation: 49

Rails ActiveRecord Associations with one to many

So, I"m not sure how to setup my associations. First, I have a User model (Devise) which has email and password.

class User < AR::Base
end

After that, I have multiple types of User models which contain more details information about the users:

class Doctor < AR::Base
  belongs_to: User
end

And:

class Nurse < AR::Base
  belongs_to: User
end

And:

class Therapist < AR::Base
  belongs_to: User
end

So, I'm not sure how the User model should relate to the others. Is my design flawed?

Thanks for helping a noob.

Upvotes: 0

Views: 195

Answers (3)

sa77
sa77

Reputation: 3603

The best way to set setup a one-to-many association between these different types of users, with minimal duplicates, would be by setting up User to belong_to these other models Doctor, Nurse and Therapist

First, setup has_many association between these models to the User model

# app/models/doctor.rb
class Doctor < ActiveRecord::Base
  has_many: :users
end

# app/models/nurse.rb
class Nurse < ActiveRecord::Base
  has_many: :users
end

# app/models/therapist.rb
class Therapist < ActiveRecord::Base
  has_many: :users
end    

Then, add migrations to add doctor_id:integer, nurse_id:integer and therapist_id:integer to users table.

Then, setup belongs_to association to other ActiveRecord models.

# app/models/user.rb
class User < ActiveRecord::Base
  belongs_to: :doctor
  belongs_to: :nurse
  belongs_to: :therapist
end

With this setup, you can access ActiveRecord data of these models as follows:

# get doctor associated to User.last
User.last.doctor
# get all the users who are patients of Doctor.last
Doctor.last.users

# get the nurse associated to User.last
User.last.nurse
# get all the users who are patients of Nurse.last
Nurse.last.users

Upvotes: 1

pauloancheta
pauloancheta

Reputation: 359

The easiest way to implement what you are trying to achieve is to have a column on user to assign a role. So you can call the methods like this:

User.add_role(:doctor)
User.has_role?(:doctor)

You can do that using this gem https://github.com/mcrowe/roleable

Another way to implement it is by using ActiveRecord Enum: http://api.rubyonrails.org/v5.1/classes/ActiveRecord/Enum.html The implementation would look like this:

User.role # => :doctor
User.doctor? # => true
User.therapist! # => true
User.role # => :therapist

I personally prefer using enums.

A complex way to do it would be to use polymorphism. Where you can put User as a polymorphic model. This blog post explains it in great detail. https://robots.thoughtbot.com/using-polymorphism-to-make-a-better-activity-feed-in-rails

Upvotes: 2

7urkm3n
7urkm3n

Reputation: 6311

Rails DB Associations Documentation Link

add these has_many's to user.rb

#user.rb
has_many :doctor 
has_many :nurse
has_many :therapist 

and You need to add user_id to doctor, nurse and therapist.

Such as like:

rails g migration add_user_id_to_nurses user_id:integer
rails g migration add_user_id_to_doctors user_id:integer
rails g migration add_user_id_to_therapits user_id:integer

Do not forget rake db:migrate at the end.

Upvotes: 1

Related Questions