Create Strong Habtm Relationships
How to create a strong has and belongs to many relationship
Section titled “How to create a strong has and belongs to many relationship”When creating has and belongs to many relationship in Rails, the best practice is as follow:
For this example, i have dogs and toys
Create your join table:
Section titled “Create your join table:”create_join_table :dogs, :toys do |t| t.references :dogs, index: true, foreign_key: true, foreign_key: { on_delete: :cascade } t.references :toys, index: true, foreign_key: true, foreign_key: { on_delete: :cascade } end
This creates our join table but also postgresql foreign keys, prevents invalid values from getting in and if the dogs or toys records are deleted, it cleans up after itself and remove the record from the join table.
The name of your join table should be conventionally by alphabetical order of the models. Since dogs is before toys the table is then going to be dogs_toys both pluralized.
Create an unique constraint to prevent duplicates:
Section titled “Create an unique constraint to prevent duplicates:”execute “ALTER TABLE dogs_toys ADD CONSTRAINT unique_dog_toys UNIQUE (dog_id, toy_id);“
Update your model to cleanup any invalid inbound values:
Section titled “Update your model to cleanup any invalid inbound values:”In dogs:
normalize :toys_idsIn toys:
normalize :dogs_idsUser Interface
Section titled “User Interface”The excellent select2 js library will delivery a rich interface to modify the records in a relationship. It’s enabled by default in crm so you just add select2 to your css class for your inputs. The input needs to be a of type hidden
<%= f.hidden_field :dogs_ids, class: "select2", data: { choices: options_to_select2_choices(f.object.list_of_dogs), multiple: true, placeholder: "Choose dog breed" } %>