0
0
Ruby on Railsframework~15 mins

Running and rolling back migrations in Ruby on Rails - Deep Dive

Choose your learning style9 modes available
Overview - Running and rolling back migrations
What is it?
Running and rolling back migrations in Rails means applying or undoing changes to the database structure. Migrations are like step-by-step instructions that tell Rails how to create, change, or remove tables and columns. Running a migration updates the database to a new state, while rolling back reverses those changes to a previous state. This helps keep the database in sync with the application code.
Why it matters
Without migrations, managing database changes would be manual, error-prone, and hard to track, especially when working with a team. Migrations let you safely evolve your database structure over time and easily undo mistakes. This keeps your app stable and your data safe as it grows and changes.
Where it fits
Before learning migrations, you should understand basic Ruby and Rails models. After mastering migrations, you can learn about database seeding, schema design, and advanced database features like indexes and constraints.
Mental Model
Core Idea
Migrations are reversible instructions that move your database schema forward or backward step-by-step.
Think of it like...
Think of migrations like a recipe book for your database. Running a migration is like following a recipe to bake a cake, and rolling back is like unbaking it to get back the original ingredients.
┌───────────────┐      ┌───────────────┐      ┌───────────────┐
│ Initial State │─────▶│ Run Migration │─────▶│ Updated State │
└───────────────┘      └───────────────┘      └───────────────┘
                             ▲
                             │
                      Rollback Migration
                             │
                             ▼
                      ┌───────────────┐
                      │ Initial State │
Build-Up - 7 Steps
1
FoundationWhat is a Rails migration
🤔
Concept: Introduce the basic idea of migrations as Ruby classes that change the database schema.
A Rails migration is a Ruby file that describes how to change the database structure. It lives in the db/migrate folder and has methods like 'change', 'up', and 'down' that tell Rails what to do. For example, creating a table or adding a column.
Result
You understand that migrations are code files that define database changes.
Understanding that migrations are code files helps you see database changes as part of your app's version history.
2
FoundationRunning migrations with rails commands
🤔
Concept: Learn how to apply migrations to update the database using Rails commands.
To run migrations, you use the command 'rails db:migrate'. This looks at all migration files and applies any that haven't run yet. It updates the database schema accordingly.
Result
The database schema changes to match the latest migration instructions.
Knowing how to run migrations lets you safely update your database structure without manual SQL.
3
IntermediateHow rollback reverses migrations
🤔Before reading on: do you think rolling back a migration always removes all changes made by that migration? Commit to your answer.
Concept: Rolling back undoes the last migration or a specific number of migrations to revert database changes.
You can undo migrations using 'rails db:rollback', which reverses the last migration by running its 'down' method or reversing the 'change' method. You can also rollback multiple steps with 'rails db:rollback STEP=n'.
Result
The database schema returns to a previous state before the rolled back migrations.
Understanding rollback helps you fix mistakes or test changes by safely stepping back in your database history.
4
IntermediateDifference between change, up, and down methods
🤔Before reading on: do you think the 'change' method can always be reversed automatically? Commit to your answer.
Concept: Migrations can define reversible changes with 'change' or explicit 'up' and 'down' methods for complex cases.
The 'change' method lets Rails know how to apply and reverse a migration automatically for simple changes like creating tables. For complex changes, you write 'up' (apply) and 'down' (undo) methods manually.
Result
You know when Rails can rollback automatically and when you must write rollback code yourself.
Knowing these methods prevents rollback errors and helps you write safe migrations.
5
IntermediateUsing rails db:migrate:status to track migrations
🤔
Concept: Learn how to check which migrations have run and which are pending.
The command 'rails db:migrate:status' lists all migrations with their version and whether they are up (applied) or down (pending). This helps you see your database migration history.
Result
You can track migration progress and diagnose issues with missing or extra migrations.
Tracking migration status helps avoid confusion and conflicts in team projects.
6
AdvancedHandling irreversible migrations safely
🤔Before reading on: do you think all migrations can be rolled back automatically? Commit to your answer.
Concept: Some migrations cannot be reversed automatically and require special care to avoid data loss.
If a migration uses commands that Rails can't reverse (like executing raw SQL or dropping tables), it is marked irreversible. You must write custom rollback code or avoid rolling back. Rails will raise an error if you try to rollback an irreversible migration.
Result
You understand the risks and how to handle migrations that can't be undone automatically.
Knowing about irreversible migrations prevents accidental data loss and forces careful planning.
7
ExpertManaging migrations in team and production environments
🤔Before reading on: do you think running migrations in production is the same as in development? Commit to your answer.
Concept: Running and rolling back migrations in production requires coordination, backups, and understanding of downtime risks.
In production, migrations must be run carefully to avoid downtime or data corruption. Rolling back in production is risky and often avoided. Teams use version control, migration locking, and backups. Sometimes, migrations are split into smaller steps or done with zero-downtime techniques.
Result
You know the best practices and risks of running migrations in real-world apps.
Understanding production migration challenges prepares you for safe database evolution in live systems.
Under the Hood
Rails stores a record of applied migrations in a special database table called schema_migrations. When you run 'rails db:migrate', Rails checks this table to see which migrations are new and runs their code. Rolling back runs the reverse code and updates the table. This tracking ensures migrations run only once and can be reversed in order.
Why designed this way?
This design keeps database changes versioned and reversible, making collaboration easier and reducing errors. Alternatives like manual SQL scripts lack tracking and safety. The schema_migrations table acts like a ledger, ensuring consistency across environments.
┌─────────────────────┐
│ Migration Files     │
│ (db/migrate/*.rb)   │
└─────────┬───────────┘
          │
          ▼
┌─────────────────────┐
│ schema_migrations   │◀─────────────┐
│ (tracks versions)   │              │
└─────────┬───────────┘              │
          │                          │
          ▼                          │
┌─────────────────────┐             │
│ Database Schema     │─────────────┘
│ (tables, columns)   │
└─────────────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does running 'rails db:rollback' undo all migrations or just the last one? Commit to your answer.
Common Belief:Running 'rails db:rollback' undoes all migrations applied so far.
Tap to reveal reality
Reality:'rails db:rollback' only reverses the last migration by default.
Why it matters:Misunderstanding this can cause confusion and accidental partial rollbacks, leading to inconsistent database states.
Quick: Can all migrations be rolled back automatically by Rails? Commit to your answer.
Common Belief:All migrations can be rolled back automatically without extra code.
Tap to reveal reality
Reality:Some migrations are irreversible and require manual rollback code or cannot be undone.
Why it matters:Assuming all migrations are reversible can cause errors and data loss when rolling back.
Quick: Does running 'rails db:migrate' re-run all migrations every time? Commit to your answer.
Common Belief:'rails db:migrate' runs all migrations every time you run it.
Tap to reveal reality
Reality:It only runs migrations that have not been applied yet, skipping those already run.
Why it matters:Thinking migrations run every time can lead to unnecessary worry about performance or data duplication.
Quick: Is rolling back migrations in production always safe and recommended? Commit to your answer.
Common Belief:Rolling back migrations in production is safe and commonly done to fix issues.
Tap to reveal reality
Reality:Rolling back in production is risky and often avoided; safer approaches involve forward fixes and backups.
Why it matters:Misusing rollback in production can cause downtime or data corruption.
Expert Zone
1
Migrations should be idempotent in development but are run only once in production, requiring careful design to avoid side effects.
2
Using reversible migration methods lets Rails handle rollback automatically, but complex schema changes often need manual 'up' and 'down' methods.
3
Schema dumping (schema.rb or structure.sql) complements migrations by providing a snapshot of the current database state for faster setup.
When NOT to use
Avoid rolling back migrations in production environments due to risk of data loss and downtime. Instead, use forward migrations to fix issues or restore from backups. For complex schema changes, consider feature flags or zero-downtime deployment techniques.
Production Patterns
Teams use migration locking to prevent concurrent runs, split large migrations into smaller steps, and run migrations during maintenance windows. Rollbacks are rare in production; instead, forward fixes and backups are preferred.
Connections
Version Control Systems
Migrations build on the idea of version control by tracking database schema changes over time.
Understanding migrations as versioned changes helps grasp how software and database evolve together safely.
Transactional Systems
Migrations often run inside database transactions to ensure all-or-nothing changes.
Knowing transactions helps understand how migrations keep databases consistent even if errors occur.
Undo/Redo Functionality in Text Editors
Rolling back migrations is like undoing changes in a text editor, stepping back through history.
This connection clarifies the concept of reversible steps and why some actions can't be undone automatically.
Common Pitfalls
#1Trying to rollback a migration that uses irreversible commands.
Wrong approach:class DropUsersTable < ActiveRecord::Migration[7.0] def change drop_table :users end end # Then running: rails db:rollback
Correct approach:class DropUsersTable < ActiveRecord::Migration[7.0] def up drop_table :users end def down create_table :users do |t| t.string :name t.timestamps end end end
Root cause:Using 'change' with irreversible commands makes Rails unable to rollback automatically.
#2Running 'rails db:migrate' multiple times expecting it to reapply all migrations.
Wrong approach:$ rails db:migrate $ rails db:migrate # expecting schema changes again
Correct approach:Run 'rails db:migrate' once; subsequent runs skip applied migrations unless new ones are added.
Root cause:Misunderstanding that migrations run only once and are tracked in the database.
#3Rolling back multiple steps without specifying the number of steps.
Wrong approach:$ rails db:rollback # only rolls back one migration, but expecting more
Correct approach:$ rails db:rollback STEP=3 # rolls back last three migrations
Root cause:Not knowing the default rollback behavior rolls back only one migration.
Key Takeaways
Migrations are code instructions that safely change your database schema step-by-step.
Running migrations applies new changes; rolling back undoes the last applied changes in reverse order.
The 'change' method is reversible for simple changes; complex changes need explicit 'up' and 'down' methods.
Rails tracks applied migrations in the database to avoid reapplying and to enable rollback.
Rolling back in production is risky; prefer forward fixes and backups to maintain data safety.