0

In my rails app I have 2 models Profile and Skill.

Profile has_and_belongs_to_many Skill and can only have one time the same Skill.

Skill has_and_belongs_to_many Profile. If we respect the first relation, it should therefore not have more than once the same Profile.

When I create my join table I have two possibilities:

rails g migration CreateProfilesSkillsJoinTable profiles:uniq skills

or

rails g migration CreateProfilesSkillsJoinTable profiles skills:uniq

The first option will generate

class CreateProfilesSkillsJoinTable < ActiveRecord::Migration[5.1]
  def change
    create_join_table :profiles, :skills do |t|
      t.index [:profile_id, :skill_id], unique: true
      # t.index [:skill_id, :profile_id]
    end
  end
end

The second will generate

class CreateProfilesSkillsJoinTable < ActiveRecord::Migration[5.1]
  def change
    create_join_table :profiles, :skills do |t|
      # t.index [:profile_id, :skill_id]
      t.index [:skill_id, :profile_id], unique: true
    end
  end
end
Daniel Costa
  • 275
  • 2
  • 14

1 Answers1

1

You want to make the index unique :

add_index :something, [:profile_id, :skill_id], unique: true

First first rule is verified (you can get 1:2 only once). Note that even with an habtm, you'll tend to create your relation the same way (profile.skills << skill), you just need to ensure skill.profiles << profile does not creates unwanted relations

Ben
  • 5,030
  • 6
  • 53
  • 94
  • I don't understand when you say `1:2` only once? Actually I'm not sure to see the difference on changing `:profile_id` with `:skill_id`. – Daniel Costa Mar 06 '18 at 09:31
  • meaning, ids, as an example profile_id=1 / skill_id: 2, only once. and yep, there's no difference. Re-reading it all, you actually have it all, I'm now unsure to understand exactly your issue – Ben Mar 06 '18 at 09:33
  • Ok, now it makes sense. But if we do the opposite index `t.index [:skill_id, :profile_id], unique: true` it will allow only once `2:1` what is the same than `1:2`. Am I wrong? – Daniel Costa Mar 06 '18 at 09:47
  • ahha actually I was puzzled by this very question, as I've used habtm for self referential (in this case, it would be an issue). But not here, no difference, profile_id will always refers to profiles, skill_id will always refers to skills. so `profile_id1:skill_id_2` is the same as `skill_id_2:profile_id1` — or i'm shamely missing the point – Ben Mar 06 '18 at 09:50