Reputation: 175
I have the following problem, A user can have several professions, more than 10. For example, a user may be a doctor, teacher, and N. Each profession has its own attributes. I could do, Doctor belongs_to User, but if I want to know all the professions of this user I will have to check each row of the User table.
I created the following code
class User < ApplicationRecord
has_many :jobables
end
class Job < ApplicationRecord
belongs_to :user
belongs_to :jobable
end
class Jobable < ApplicationRecord
has_one :job
end
class Medic < Jobable
end
class Programmer < Jobable
end
But I do not know if that would be the best answer
Upvotes: 5
Views: 74
Reputation: 20253
I would think that it would be much easier to do something like:
class User < ApplicationRecord
has_many :user_professions
has_many :professions, through: :user_professions
end
# == Schema Information
#
# Table name: professions
#
# id :integer not null, primary key
# name :string
# created_at :datetime not null
# updated_at :datetime not null
#
class Profession < ApplicationRecord
has_many :user_professions
has_many :users, through: :user_professions
end
class UserProfession < ApplicationRecord
belongs_to :user
belongs_to :profession
end
You could then create logic to ensure that a Profession
is only assigned to a User
once.
Then, you could simply do:
@user.professions
And get all the Profession
s for a User
.
You could also do:
@profession.users
And get all the User
s that belong to the Profession
.
Based on the edit to your question, you could do something like:
class UserProfession < ApplicationRecord
belongs_to :user
belongs_to :profession
belongs_to :profession_detail, polymorphic: true
end
In which case you might have something like:
class DoctorDetail < ApplicationRecord
end
And you could do something like:
@user.professional_detail_for(:doctor)
Of course, you would need to implement the professional_detail_for
method on the User
model which might look something like:
class User < ApplicationRecord
has_many :user_professions
has_many :professions, through: :user_professions
def professional_detail_for(profession_type)
user_profession_for(profession_for(profession_type)).try(:profession_detail)
end
private
def profession_for(profession_type)
Profession.find_by(name: profession_type.to_s)
end
def user_profession_for(profession)
user_professions.find_by(profession: profession)
end
end
That's a little rough, but I imagine you get the idea.
Upvotes: 5