Ruby on Rails Model / Database Associations - ruby-on-rails

I have a user model, farmer model, doctor model, and education model.
A farmer has a user and many educations.
A doctor has a user and many educations.
How do I setup the database for the education model?
Should it have a farmer_id AND a doctor_id?
But a education cannot belong to a farmer AND and doctor at the same time. It's one or the other.
So my education database entry would either have a farmer_id OR a doctor_id filled in, but not both.
Is there a way to guarantee that only one of the ids could be filled in at a time?
Or is there a better way to associate these models?
Your help would be appreciated!
Oh, and don't worry about the names of the models (farmer, doctor, etc.). It's just an example.

I see two possible solutions for this scenario.
The first one is to make use of polymorphic associations for education. That could look like this:
class Farmer < ActiveRecord::Base
belongs_to :user
has_many :educations, :as => :profession
end
class Doctor < ActiveRecord::Base
belongs_to :user
has_many :educations, :as => :profession
end
class Education < ActiveRecord::Base
belongs_to :profession, :polymorphic => true
end
So instead of education having a doctor_id or a farmer_id it has one profession_id and one profession_type.
The second solution would be to make use of Single Table Inheritance. And in your scenrio, that could be accomplished by letting a Doctor be a User instead of belonging to a User. And of course the same thing for a Farmer. That could look like this:
class User < ActiveRecord::Base
has_many :educations
end
class Farmer < User
end
class Doctor < User
end
class Education < ActiveRecord::Base
belongs_to :user
end
And in this scenario you would add a type column to the User model to store what type of class it is and then only having a user_id in the Education model

I think its appropriate to have the relations this way based on roles.
Class User
has_one :role
has_many :educations
end
Class Role
#What ever roles you have.
#Farmer or Doctor
belongs_to :user
end
class Education
belongs_to :user
end
This way you will store the user_id in the education object, which solves your problem.

Related

ActiveRecord association through multiple tables

I have the following schema for my Rails app :
A project has many reviews, each of those reviews is filled out by a unique User to calculate a global score.
We could say that "An Organization of Users handles many Entities that have many Projects which are reviewed by the Users".
As you can see, I have a circular reference since I linked the tables "Users" & "Reviews".
After many tries and many search, I just can't manage to associate a User to a Review...Here is what I did so far:
1. Creation of an association table "UserReviews"
2. Model User
class User < ApplicationRecord
belongs_to :organization
####
has_many :user_reviews
has_many :reviews, through: :user_reviews
end
3. Model Review
class Review < ApplicationRecord
belongs_to :project
##
belongs_to :user_reviews
has_one :user, through: :user_reviews
end
4. Model UserReview
class UserReview < ApplicationRecord
belongs_to :user
belongs_to :review
end
I want to be able to get user.reviews or review.user.
Basically...I have to admit I'm lost despite the documentation. I never had to deal with this kind of issue.
Many thanks for your help!
Why do you need UserReview model here? I suppose Review model suffices your use case.
Change the Review model to:
class Review < ApplicationRecord
belongs_to :project
belongs_to :user
end

Active Record - Joining same table multiple times

I have a model A which belongs to my User model. I also have a model B, which belongs to my B model and also my User model (those are two different users, like doctor and patient). What I would like to do is some query like this:
B.joins(:user, {a: :user}).where("patient.name = 'some condition' or doctor.name='some other condition'")
The point here is: how can I specify that the users.name I'm querying is the one which is associated to A or B model?
Any help will be appreciated, thanks!
Perhaps something like this could work? (I haven't tested the code)
class User < ApplicationRecord
has_many :doctors
has_many :patients, through: :doctors
end
class Doctor < ApplicationRecord
belongs_to :user
has_many :patients
end
class Patient < ApplicationRecord
belongs_to :doctor
belongs_to :user
end
Patient.joins(user: {doctors: :user}).where("patient.name = 'some condition' or doctor.name='some other condition'")
Hope this helps!
You can create new classes named Patient and Doctor that inherit from User, then refer to users as patients and doctors instead of generic users.
class Doctor < User
has_many :a
end
class Patient < User
has_many :b
end
This is Single Table Inheritance:
https://api.rubyonrails.org/classes/ActiveRecord/Inheritance.html

How to model invoice that can belong to either a person or a company?

In my Ruby on Rails application I have invoices which can belong to either a person or a company. To make things even more complicated, a person can also belong to a company.
I figured that the right way to model this in Rails would be something like this:
class Invoice < ApplicationRecord
belongs_to :invoiceable, polymorphic: true
end
class Person < ApplicationRecord
has_many :invoices, as: :invoiceable
end
class Company < ApplicationRecord
has_many :invoices, as: :invoiceable
end
Is this the right way to do it?
And if so, can a person still belong to a company this way?
Thanks for any help.

Rails 3 model association

I have the following models:
User, ProcessType and Remark, as follows:
class User < ActiveRecord::Base
has_many :process_type
end
class Remark < ActiveRecord::Base
belongs_to :process_type
end
class ProcessType < ActiveRecord::Base
belongs_to :user
has_many :remarks
end
only some Users are associated with a ProcessType. When a Remark is added, it gets associated with a certain ProcessType (and each ProcessType has a User responsible). I want that when the User associated with a certain ProcessType logs in, to see all Remarks of that processType.
I am not able to figure out the correct approach, maybe someone could help me.
Thanks!
in User.rb, you can have association with remarks directly since user is associated with process_type and process_type is associated with remarks
has_many :remarks, :through => :process_type
Then to see all remarks you can write this ActiveRecord query
current_user.remarks

Rails Associations for Lookup Table

I have a Statuses table which contains only an id and name field (Active, Inactive, Pending, etc). I then have tables such as Users, Achievements, Badges for which each of these contain a status_id foreign key. Do the associations in my models look correct?
class Status < ActiveRecord::Base
has_many :achievements
has_many :badges
has_many :users
end
class User < ActiveRecord::Base
belongs_to :status
end
class Badge < ActiveRecord::Base
belongs_to :status
end
class Achievement < ActiveRecord::Base
belongs_to :status
end
I am struggling with how to properly read the difference between has_one and has_many in the case of a lookup table. I know that a user has one company and has one profile and a company has many users but this seems backwards to me.
The simplest association setup would be:
class User < ActiveRecord::Base
has_one :status
end
That exactly describes what you have posted. Your solution would work, but it is overkill for what you've described. All the association I posted above would do is add one method to the user model, i.e.
#user = User.find(1)
#user.status
If on the other hand you wanted simple semantics for showing all the users with a particular status, THEN you'd add
class Status < ActiveRecord::Base
has_many :users
end
so now you could do:
#status = Status.find_by_description('Active').first()
#status.users
Note that in BOTH cases, all that is needed is for the users model to have an attribute 'status_id'
Belongs_to is better suited when there is an implicit hierarchy , i,e,
class Child << ActiveRecord::Base
belongs_to :parent
end

Resources