Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Polymorphic has_many through Associations in Ruby on Rails

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

like image 648
Alaina Wilkins Avatar asked May 07 '18 23:05

Alaina Wilkins


People also ask

What is polymorphic association in Ruby on Rails?

In Ruby on Rails, a polymorphic association is an Active Record association that can connect a model to multiple other models. For example, we can use a single association to connect the Review model with the Event and Restaurant models, allowing us to connect a review with either an event or a restaurant.

What is Active Record in Ruby on Rails?

What is ActiveRecord? ActiveRecord is an ORM. It's a layer of Ruby code that runs between your database and your logic code. When you need to make changes to the database, you'll write Ruby code, and then run "migrations" which makes the actual changes to the database.


1 Answers

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 Professions for a User.

You could also do:

@profession.users 

And get all the Users 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.

like image 182
jvillian Avatar answered Oct 06 '22 00:10

jvillian