0

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.

2 Answers 2

2

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

Sign up to request clarification or add additional context in comments.

9 Comments

Every time i've used STI in rails i've bitterly regretted it. I don't know if it's just me being dumb or if it just sucks. I would go with the polymorphic relationship solution.
Polymorphic would probably be my choice as well.
So the Profession model has a profession_id and profession_type? Both would be integer fields in the database? I could have the profession_type represented by an enum in the Profession model?
The Education model has a profession_id and profession_type, yes. The profession_id is an integer but the profession_type is a string (or varchar in database)
Good to hear it worked out. Another way you could have done it in the console would be f1=Doctor.new;f1.save;f2=f1.educations.build;f2.save The build method lets you associate at the same time as you instantiate a model.
|
2

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.

2 Comments

Your comment "Whatever roles you have. Farmer or Doctor." Does that mean I should have, for example: class Doctor belongs_to :user end or what? I don't get it. Or am I supposed to have a enum that represents role type? And that enum would be stored in the Role table as an integer?
Not necessarily, you ll have only 2 records in the Role table. Role will basically have, these fields. Role.create(:name => "Farmer"), Role.create(:name => "Doctor"). And then you ll have to store the id of that role object in the respective user object.User.create(:role_id => what_ever_id_of_the_role, :all_your_fields)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.