When creating a database table for a join model without further importance, you can use Rails' create_join_table:
class CreateSchoolsStudents < ActiveRecord::Migration[7.2]
def change
create_join_table :schools, :students, column_options: { foreign_key: true } do |t|
t.index [:student_id, :school_id], unique: true
end
end
end
This will create a table without an id column and without timestamps. It will have school_id and student_id columns with null: false constraints and indexes.
-
null: falseprevents creation of join records without associations. - The
foreign_key: trueprevents deletion of a joined record. Setdependent: :destroyon yourhas_many :schools_studentsassociation in both models to remove join records together with their model records. - The optional unique index prevents duplicate join records.
More control
If you need more flexibility, e.g. the table models a distinct entity, write your migration like this:
class CreateSchoolsStudents < ActiveRecord::Migration[7.2]
def change
create_table :schools_students do |t|
t.timestamps
# More columns ...
t.references :student, null: false, foreign_key: true
t.references :school, null: false, foreign_key: true
t.index [:student_id, :school_id], unique: true
end
end
end
t.references automatically adds an index. If you're using the compound index at the end, you can avoid a duplicate index by calling t.references :student with index: false.
Posted by Dominik Schöler to makandra dev (2025-11-27 06:56)