A migration is a Ruby class that changes the database schema one step at a time, so the schema evolves in a consistent way. You describe the change in a Ruby domain-specific language (DSL) instead of SQL. A migration written only in this DSL works on any database Rails supports.
Each file name starts with a timestamp, and Rails records the ones it ran in the schema_migrations table. That gives the schema version control.
Teammates get new migrations with the code and run bin/rails db:migrate to catch up.
Rollback with bin/rails db:rollback reverts the last migration. Rails can reverse a change method by itself when every command in it is reversible, like create_table or add_column. Raw SQL and other irreversible steps need separate up and down methods.
class CreateUsers < ActiveRecord::Migration[7.0]
def change
create_table :users do |t|
t.string :email
t.timestamps
end
end
end
Each run updates db/schema.rb, the schema snapshot used to build a fresh database.
Rewriting in plainer words…
This answer doesn't lend itself to a diagram - it reads best . No credits were charged.