Rails: Join model table migration template

Posted . Visible to the public.

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: false prevents creation of join records without associations.
  • The foreign_key: true prevents deletion of a joined record. Set dependent: :destroy on your has_many :schools_students association 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.

Profile picture of Dominik Schöler
Dominik Schöler
Last edit
Dominik Schöler
License
Source code in this card is licensed under the MIT License.
Posted by Dominik Schöler to makandra dev (2025-11-27 06:56)