For defining many_to_many(m2m) relations you need to define aPivot(junction) table and a foreign_key / unique constraint(index).
Naming of the Pivot table requires models to be ordered alphabetically and in singular form. For instance a Pivot table between the models Tag and user should be named tag_user.
⭕tag_user
❌user_tag -> Not ordered alphabetically
❌tag_users -> Not in singular form
❌tags_users -> Not in singular form
Let's define a User has_many Tags through "tag_user" pivot table (many_to_many) relation for example.
classAddUsers<ActiveRecord::Migration[7.0]defchange create_table :usersdo|t|# "id" primary key column will also be added implicitly by Rails(ActiveRecord) t.string:email,null:falseendendend
classAddTags<ActiveRecord::Migration[7.0]defchange create_table :tagsdo|t| t.string:label,null:falseend# Use "label" as the primary key column add_index :tags,:label,unique:trueendend
classAddTagUser<ActiveRecord::Migration[7.0]defchange create_table :tag_userdo|t| t.string:tag_label,null:false t.bigint:user_id,null:falseend# Foreign key to "Tag" table, # references "tags.label" instead of default "tags.id" in this case add_foreign_key :tag_user,:tags,column::tag_label,primary_key::label# Foreign key to "User" table. add_foreign_key :tag_user,:users,column::user_id# Pivot table need to have a "multiple unique constraint" for both tables' columns. add_index :tag_user, [:tag_label,:user_id],unique:trueendend
Resulting Model Relations
With the DB setup above, EzQL will generate the following Model Relations.
# Code generated by EzQL, DO NOT EDIT.classUser<ApplicationRecord has_many :tag_user,foreign_key::user_id,dependent::destroy has_many :tags,through::tag_userend
# Code generated by EzQL, DO NOT EDIT.classTagUser<ApplicationRecord self.table_name="tag_user" belongs_to :tag,foreign_key::tag_label,primary_key::label belongs_to :user,foreign_key::user_idend
# Code generated by EzQL, DO NOT EDIT.classTag<ApplicationRecord has_many :tag_user,foreign_key::tag_label,primary_key::label,dependent::destroy has_many :users,through::tag_userend