Documentation

Complete guide to using Rails Migration Guard in your projects.

Installation

Requirements

  • Rails 6.1+ through Rails 8.0 (tested with Rails 8.0.2)
  • Ruby 3.0+ (Ruby 3.2+ required for Rails 8.0)
  • Git (for branch tracking)

Add to Gemfile

# Add to your Gemfile
group :development, :staging do
  gem 'rails_migration_guard'
end

Install and Setup

# Install the gem
$ bundle install

# Generate the migration and configuration
$ rails generate migration_guard:install

# Run the migration to create the tracking table
$ rails db:migrate

Note: The gem only runs in development and staging environments by default. It won't affect your production performance.

Quick Start

Once installed, Rails Migration Guard works automatically. See our comprehensive Quick Start Guide for detailed workflow examples. Here's how to verify it's working:

# Check your current migration status
$ rails db:migration:status

# Run diagnostics to verify setup
$ rails db:migration:doctor

Your First Migration

Create and run a migration to see tracking in action:

# Create a new migration
$ rails generate migration AddNameToUsers name:string

# Run the migration (this will be tracked automatically)
$ rails db:migrate

# Check the status to see your tracked migration
$ rails db:migration:status

Configuration

Rails Migration Guard works out of the box, but you can customize its behavior:

# config/initializers/migration_guard.rb
MigrationGuard.configure do |config|
  # Environments where MigrationGuard is active
  config.enabled_environments = [:development, :staging]
  
  # Git integration level
  config.git_integration_level = :warning  # :off, :warning, :auto_rollback
  
  # Branch configuration
  config.main_branch_names = %w[main master trunk]
  
  # Behavior options
  config.warn_on_switch = true
  config.auto_cleanup = false
  config.cleanup_after_days = 30
  
  # Tracking options
  config.track_author = true       # Capture git user.email with migrations
  config.track_branch = true       # Track which branch created the migration
  config.track_timestamp = true    # Record execution timestamps
  
  # Logging
  config.log_level = :info
  config.colorize_output = true
end

Configuration Options

Option Default Description
enabled_environments [:development, :staging] Environments where the gem is active
git_integration_level :warning Level of git integration (:off, :warning, :auto_rollback)
main_branch_names ["main", "master"] Names to check for the main branch
warn_on_switch true Show warnings when switching branches
track_author true Capture git user.email when tracking migrations

Basic Commands

Check Migration Status

$ rails db:migration:status

Shows a comprehensive report of all migrations, their sync status with the main branch, and identifies orphaned migrations.

Rollback Orphaned Migrations

$ rails db:migration:rollback_orphaned

Interactively rollback migrations that exist locally but not in the main branch. You'll be prompted to confirm each rollback.

Recovery Tools

# Analyze and recover from inconsistent migration states
$ rails db:migration:recover

# Run in automatic mode (for CI/CD)
$ AUTO=true rails db:migration:recover

Comprehensive tools for recovering from failed rollbacks and inconsistent migration states. Detects and fixes:

  • Partial rollbacks stuck in "rolling_back" state
  • Orphaned schema changes without tracking records
  • Missing migration files for applied migrations
  • Version conflicts and duplicate records

Includes automatic database backup before recovery operations for safety.

Run Diagnostics

$ rails db:migration:doctor

Runs comprehensive diagnostics to check your setup, git integration, and identify potential issues.

Cleanup Old Records

$ rails db:migration:cleanup FORCE=true

Removes old tracking records based on your cleanup policy. Use FORCE=true to actually perform the cleanup.

View Migration History

$ rails db:migration:history              # View recent history
$ rails db:migration:history BRANCH=main  # Filter by branch
$ rails db:migration:history DAYS=7       # Last 7 days
$ rails db:migration:history AUTHOR=alice # Filter by author

Shows detailed migration execution history with filtering options.

View Author Statistics

$ rails db:migration:authors

Displays comprehensive author statistics showing who created migrations and their contribution breakdown.

Migration Recovery

Rails Migration Guard includes powerful recovery tools to help fix inconsistent migration states that can occur during development.

Analyze Migration Issues

$ rails db:migration:recover

Detects and helps resolve various migration inconsistencies including:

  • Migrations stuck in rolling_back state
  • Schema entries without tracking records
  • Missing migration files
  • Duplicate tracking records
  • Migrations applied but missing from schema

Interactive Recovery Mode

# Interactive mode (default)
$ rails db:migration:recover

⚠️  Detected migration inconsistencies:

1. Partial rollback
   Version: 20240115123456
   Migration appears to be stuck in rollback state
   Severity: HIGH
   Branch: feature/user-prefs
   Last updated: 2024-01-15 14:30:45
   Recovery options: complete_rollback, restore_migration, mark_as_rolled_back

Select option (0-3): 

Prompts for action on each detected issue with multiple recovery strategies.

Automatic Recovery Mode

# Automatic mode for CI/CD
$ AUTO=true rails db:migration:recover

Automatically applies the first recovery option for each issue. Useful for CI/CD pipelines.

Recovery Features

  • Automatic Database Backups: Creates backups before any recovery operation (PostgreSQL, MySQL, SQLite)
  • Multiple Recovery Strategies: Different approaches for each type of inconsistency
  • Git Integration: Can restore missing migration files from git history
  • Safe Operations: All commands use parameterized queries and safe execution methods

Common Recovery Scenarios

Stuck Rollback

Migration started rolling back but didn't complete:

  • Complete Rollback: Finish the rollback operation
  • Restore Migration: Re-apply the migration
  • Mark as Rolled Back: Update status without changes

Orphaned Schema

Migration in schema_migrations but not tracked:

  • Track Migration: Create tracking record
  • Remove from Schema: Delete the schema entry

Missing File

Tracking record exists but migration file is missing:

  • Restore from Git: Recover file from git history
  • Mark as Resolved: Acknowledge the missing file

Common Workflows

Switching Branches

  1. 1. Check migration status before switching: rails db:migration:status
  2. 2. Switch to your target branch: git checkout main
  3. 3. Review any warnings about orphaned migrations
  4. 4. Rollback orphaned migrations if needed: rails db:migration:rollback_orphaned
  5. 5. Run any missing migrations: rails db:migrate

Before Merging a PR

  1. 1. Ensure you're on your feature branch
  2. 2. Run status check: rails db:migration:status
  3. 3. Verify no orphaned migrations exist
  4. 4. Commit all migration files to your branch
  5. 5. Push with confidence

Handling Orphaned Migrations

When you see orphaned migrations:

  • • Review each migration to understand what it does
  • • Check if the migration should be kept (move to main branch)
  • • Or rollback if it was experimental or belongs to abandoned features
  • • Use the interactive rollback to make informed decisions

Git Integration

Rails Migration Guard can integrate with Git to automatically detect branch changes and warn about migration conflicts.

Install Git Hooks

# Install post-checkout hook (warns on branch switch)
$ rails generate migration_guard:hooks

# Install pre-push hook (prevents pushing with orphaned migrations)
$ rails generate migration_guard:hooks --pre-push

Recommended: Install both hooks for the best experience. The post-checkout hook provides immediate feedback, while the pre-push hook prevents accidentally pushing orphaned migrations.

Integration Levels

:off

No git integration. Manual checking only.

:warning (default)

Shows warnings about orphaned migrations when switching branches or pushing.

:auto_rollback

Automatically prompts to rollback orphaned migrations when switching to main branch.

Troubleshooting

Common Issues

Git not found

Ensure Git is installed and available in your PATH.

$ which git

Migration tracking table not found

Run the installation generator to create the tracking table.

$ rails generate migration_guard:install && rails db:migrate

Hooks not working

Check that git hooks are executable and properly installed.

$ ls -la .git/hooks/ | grep migration

Debug Mode

Enable debug logging to troubleshoot issues:

# Enable debug logging
$ MIGRATION_GUARD_DEBUG=true rails db:migration:status

# Or set in your initializer
MigrationGuard.configure do |config|
  config.log_level = :debug
end

Getting Help

If you're still having issues:

  • • Run rails db:migration:doctor for diagnostic information
  • • Check the GitHub issues for similar problems
  • • Open a new issue with your diagnostic output

API Reference

Complete reference for Rails Migration Guard's programmatic API and configuration options.

Configuration API

MigrationGuard.configure

Main configuration method for setting up Migration Guard behavior.

MigrationGuard.configure do |config|
  # Configuration options here
end
config.enabled_environments

Array of environments where Migration Guard is active.

config.enabled_environments = [:development, :staging]
config.git_integration_level

Level of Git integration. Options: :off, :warning, :auto_rollback

config.git_integration_level = :warning
config.main_branch_names

Array of branch names to consider as the main branch.

config.main_branch_names = %w[main master trunk]

Rake Tasks

db:migration:status

Shows comprehensive migration status report

rails db:migration:status

db:migration:rollback_orphaned

Interactively rollback orphaned migrations

rails db:migration:rollback_orphaned

db:migration:doctor

Run comprehensive diagnostics

rails db:migration:doctor

db:migration:cleanup

Clean up old tracking records

rails db:migration:cleanup FORCE=true

db:migration:history

View migration execution history

rails db:migration:history AUTHOR=email

db:migration:recover

Analyze and recover from inconsistent migration states

rails db:migration:recover

db:migration:authors

View author statistics and contributions

rails db:migration:authors

db:migration:recover

Analyze and recover from inconsistent migration states

rails db:migration:recover

Ruby API

MigrationGuard::Reporter

Generate migration status reports programmatically.

# Create a reporter instance
reporter = MigrationGuard::Reporter.new

# Get status report data
report = reporter.status_report
# Returns: { current_branch:, main_branch:, synced_count:, orphaned_count:, orphaned_migrations:, missing_migrations: }

# Get formatted output
output = reporter.format_status_output
puts output

MigrationGuard::Tracker

Track migrations programmatically.

# Create a tracker instance
tracker = MigrationGuard::Tracker.new

# Track a migration manually
tracker.track_migration('20240116123456', :up)

# Check if migration exists
tracker.migration_tracked?('20240116123456')

# Clean up old records
tracker.cleanup_old_records
# Returns: number of records cleaned

MigrationGuard::GitIntegration

Access Git information and branch details.

# Create git integration instance
git = MigrationGuard::GitIntegration.new

# Get current branch
current_branch = git.current_branch

# Get main branch name
main_branch = git.main_branch

# Get migration versions in trunk
trunk_migrations = git.migration_versions_in_trunk
# Returns: Array of migration version strings

MigrationGuard::RecoveryAnalyzer

Detect inconsistent migration states that need recovery.

# Create analyzer instance
analyzer = MigrationGuard::RecoveryAnalyzer.new

# Analyze migration inconsistencies
issues = analyzer.analyze
# Returns: Array of issue hashes with :type, :version, :severity, :recovery_options

# Check if there are issues
if analyzer.issues?
  # Get formatted report
  report = analyzer.format_analysis_report
  Rails.logger.info report
end

# Issue types detected:
# - :partial_rollback (stuck in rolling_back state)
# - :orphaned_schema (in schema_migrations but not tracked)
# - :missing_file (tracked but file missing)
# - :version_conflict (duplicate tracking records)

MigrationGuard::RecoveryExecutor

Execute recovery actions for inconsistent migration states.

# Create executor instance
executor = MigrationGuard::RecoveryExecutor.new(interactive: false)

# Execute recovery for an issue
issue = analyzer.analyze.first
success = executor.execute_recovery(issue, :complete_rollback)

# Recovery options include:
# - :complete_rollback - Finish incomplete rollback
# - :restore_migration - Re-apply migration
# - :mark_as_rolled_back - Update status only
# - :track_migration - Create tracking record
# - :remove_from_schema - Delete schema entry
# - :consolidate_records - Merge duplicate records

# Access backup path after recovery
backup_path = executor.backup_path if executor.backup_path

MigrationGuard::Rollbacker

Safely rollback orphaned migrations.

# Create rollbacker instance
rollbacker = MigrationGuard::Rollbacker.new

# Get orphaned migrations
orphaned = rollbacker.orphaned_migrations

# Rollback a specific migration
success = rollbacker.rollback_migration('20240116123456')

# Rollback all orphaned migrations
rollbacker.rollback_all_orphaned(force: true)

# Interactive rollback (prompts for each)
rollbacker.rollback_orphaned_interactively

MigrationGuard::AuthorReporter

Generate author statistics and contribution reports.

# Create author reporter instance
author_reporter = MigrationGuard::AuthorReporter.new

# Get author statistics
stats = author_reporter.authors_summary
# Returns: { total_authors:, total_migrations:, most_active:, average_per_author:, current_user: }

# Get per-author breakdown
authors = author_reporter.authors_report
# Returns: Array of author data with counts by status

# Get formatted report
output = author_reporter.format_authors_report
puts output

Events and Hooks

Migration Callbacks

Hook into migration events for custom behavior.

# In an initializer or model
MigrationGuard.configure do |config|
  # Called after migration is tracked
  config.on_migration_tracked = ->(migration_record) do
    Rails.logger.info "Tracked migration: #{migration_record.version}"
    # Send notification, update external systems, etc.
  end
  
  # Called when orphaned migrations are detected
  config.on_orphans_detected = ->(orphaned_migrations) do
    # Send alerts, notifications, etc.
    SlackNotifier.notify("#{orphaned_migrations.count} orphaned migrations detected")
  end
end

Error Classes

MigrationGuard::Error

Base error class for all Migration Guard errors

MigrationGuard::GitError

Raised when Git operations fail

MigrationGuard::MigrationNotFoundError

Raised when trying to rollback a non-existent migration

MigrationGuard::RollbackError

Raised when migration rollback fails