jpereira
jpereira

Reputation: 251

has_many used twice in the same model

I have 2 classes Job and a Skill and between them there are 2 relations

  1. To do a Job, you require many Skills
  2. To do a Job, would be nice to have many Skills

These are the classes that I have

class Job < ActiveRecord::Base
  has_many required, class_name: 'Skill', :through => JobSkill
  has_many nice_to_have, class_name: 'Skill', :through => JobSkill
end

class Skill < ActiveRecord::Base
  has_many :jobs
end

but I am missing the connector between them.

class JobSkill < ActiveRecord::Base
   belongs_to :skill
   belongs_to :required, class_name 'Job', 
   belongs_to :nice_to_hace, class_name 'Job'
end

As tables I would have:

create_table :jobs do |t|
  t.string :job_identifier
  t.references :requirement
  t.references :nice_to_have
end
create_table :skills do |t|
  t.string :name
end
create_table :job_skills do |t|
  t.references :requirement
  t.references :nice_to_have
  t.integer    :skill_id
end

Is this a correct representation? Because looking into the model I am not sure if I have all the connections

Are the references enough to connect all the tables or do I need to use :foreign_key in the connections?

Upvotes: 3

Views: 420

Answers (1)

Mark Swardstrom
Mark Swardstrom

Reputation: 18130

I think I would do this

class Job < ActiveRecord::Base
  has_many :job_skills
  has_many :skills, :through => :job_skills
end

class JobSkill < ActiveRecord::Base
  belongs_to :job
  belongs_to :skill

  # add boolean attribute :required
end

class Skill < ActiveRecord::Base
  has_many :job_skills
  has_many :jobs, :through => :job_skills
end

This way you can add skills and later decide if they are nice to have or required.

create_table :jobs do |t|
  t.string :job_identifier
end

create_table :skills do |t|
  t.string :name
end

create_table :job_skills do |t|
  t.references :job
  t.references :skill
  t.boolean :required, default: false, null: false
end

And, to get nice-to-have OR required skills for the job, you can add this has_many

class Job < ActiveRecord::Base
  has_many :job_skills
  has_many :skills, :through => :job_skills

  has_many :required_skills, -> { where job_skills: { required: true } }, through: :job_skills, class_name: 'Skill', source: :skill
  has_many :nice_to_have_skills, -> { where job_skills: { required: false } }, through: :job_skills, class_name: 'Skill', source: :skill
end

Upvotes: 2

Related Questions