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 :users do|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 :tags do|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_user do|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