Examples & Workflows

Real-world examples of how Rails Migration Guard helps teams manage database migrations across branches.

Feature Development Workflow

Scenario: Adding a new feature with database changes

📝 The Situation

  • • You're working on a user profiles feature
  • • Need to add several new database tables
  • • Multiple developers on different features
  • • Want to avoid migration conflicts

✅ How Migration Guard Helps

  • • Tracks all migrations by branch
  • • Warns when switching branches
  • • Easy rollback of experimental changes
  • • Prevents pushing orphaned migrations

🚀 Step-by-Step Workflow

1

Create your feature branch

$ git checkout -b feature/user-profiles
2

Generate and run migrations

$ rails g migration CreateUserProfiles name:string bio:text $ rails g migration AddAvatarToUsers avatar_url:string $ rails db:migrate
→ Migration Guard automatically tracks both migrations
3

Check migration status

$ rails db:migration:status
Migration Status (feature/user-profiles → main)
✓ Synced: 45 migrations
⚠ Orphaned: 2 migrations (local only)
→ Your new migrations are tracked as orphaned (expected!)
4

Need to switch to main for a hotfix?

$ git checkout main
⚠️ Warning: 2 orphaned migrations detected on feature/user-profiles
$ rails db:migration:rollback_orphaned
→ Safely rollback your feature migrations before switching
5

Return to your feature and continue

$ git checkout feature/user-profiles $ rails db:migrate
→ Your migrations are re-applied and tracking continues

Step 1: Create feature branch and migrations

# Create and switch to feature branch
$ git checkout -b feature/user-profiles

# Create migrations for your feature
$ rails generate migration CreateUserProfiles user:references bio:text avatar_url:string
$ rails generate migration AddProfileSettingsToUsers show_email:boolean show_phone:boolean

# Run migrations (automatically tracked by Migration Guard)
$ rails db:migrate

Step 2: Check what's been tracked

$ rails db:migration:status
Migration Status Report
Current branch: feature/user-profiles → main branch

✓ Synced: 10 migrations
⚠ Orphaned: 2 migrations

Orphaned Migrations:
• 20240116123456_create_user_profiles.rb (feature/user-profiles, 5 minutes ago)
• 20240116123457_add_profile_settings_to_users.rb (feature/user-profiles, 3 minutes ago)

Step 3: Switch back to main (with automatic warning)

$ git checkout main
⚠ MigrationGuard: 2 orphaned migrations detected

Migrations that exist locally but not in main:
  - 20240116123456 (CreateUserProfiles)
  - 20240116123457 (AddProfileSettingsToUsers)

These migrations were created on: feature/user-profiles
Consider running: rails db:migration:rollback_orphaned

Step 4: Rollback orphaned migrations

$ rails db:migration:rollback_orphaned
Found 2 orphaned migrations:

1. CreateUserProfiles (20240116123456)
   Branch: feature/user-profiles
   Author: dev@example.com
   Age: 10 minutes

   Rollback this migration? (y/n): y
   ✓ Rolled back successfully

2. AddProfileSettingsToUsers (20240116123457)
   Branch: feature/user-profiles
   Author: dev@example.com
   Age: 8 minutes

   Rollback this migration? (y/n): y
   ✓ Rolled back successfully

All orphaned migrations have been cleaned up!

Step 5: Return to feature branch

# Switch back to feature branch
$ git checkout feature/user-profiles

# Re-run the migrations
$ rails db:migrate

# Continue developing...
$ rails db:migration:status  # Shows orphaned migrations again

Team Collaboration Scenario

Multiple developers, multiple features, shared staging

👩‍💻 Alice

Working on user authentication (branch: auth-system)

👨‍💻 Bob

Building payment system (branch: payments)

👩‍💻 Carol

Adding admin panel (branch: admin-panel)

Problem: Conflicting migrations in staging

When deploying to staging, migrations from different branches conflict, causing deployment failures and database inconsistencies.

Solution: Pre-push hooks prevent the problem

# Each developer installs pre-push hooks
$ rails generate migration_guard:hooks --pre-push

Alice tries to push her auth-system branch:

$ git push origin auth-system
Pre-push check: Checking for orphaned migrations...

✓ No orphaned migrations found
✓ Safe to push

Pushing to origin/auth-system...

Bob tries to push, but has orphaned migrations:

$ git push origin payments
Pre-push check: Checking for orphaned migrations...

⚠ Found 3 orphaned migrations:
  - 20240116001122_create_payment_methods.rb
  - 20240116001123_create_transactions.rb  
  - 20240116001124_add_payment_status_to_orders.rb

These migrations exist locally but not in main branch.
Push blocked to prevent staging conflicts.

To resolve:
1. rails db:migration:rollback_orphaned (if experimental)
2. Or merge these migrations to main first
3. Then retry push

CI/CD Pipeline Integration

Preventing deployment issues with automated checks

GitHub Actions Workflow

# .github/workflows/deploy.yml
name: Deploy to Staging
on:
  push:
    branches: [staging]

jobs:
  migration-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: 3.1
          bundler-cache: true
      
      - name: Check for orphaned migrations
        run: |
          bundle exec rails db:create
          bundle exec rails db:migrate
          bundle exec rails db:migration:status
          
          # Fail if orphaned migrations found
          if bundle exec rails db:migration:check --orphaned; then
            echo "✅ No orphaned migrations found"
          else
            echo "❌ Orphaned migrations detected - deployment blocked"
            exit 1
          fi
      
      - name: Deploy to staging
        if: success()
        run: ./deploy-staging.sh

Heroku Integration

# In your Heroku build process
echo "Checking migration status before deployment..."

if bundle exec rails db:migration:check --orphaned; then
  echo "✅ Migration check passed"
else
  echo "❌ Orphaned migrations found - stopping deployment"
  exit 1
fi

# Continue with normal deployment
bundle exec rails db:migrate

Command Examples

Migration Status

$ rails db:migration:status
Migration Status Report
Current branch: feature/api-v2 → main branch

✓ Synced: 15 migrations
⚠ Orphaned: 3 migrations
✗ Missing: 1 migration

Orphaned Migrations:
• 20240116123456_create_api_keys.rb (feature/api-v2, 2 hours ago)
• 20240116123457_add_rate_limits.rb (feature/api-v2, 1 hour ago)
• 20240116123458_create_webhooks.rb (feature/api-v2, 30 minutes ago)

Missing Migrations:
• 20240116120000_fix_user_indexes.rb (in main, not applied locally)

💡 Run `rails db:migration:rollback_orphaned` to clean up
💡 Run `rails db:migrate` to apply missing migrations

Diagnostics

$ rails db:migration:doctor
MigrationGuard Diagnostics
==========================

Environment Check:
✓ Rails environment: development
✓ MigrationGuard enabled: true
✓ Database connection: OK

Git Integration:
✓ Git repository: detected
✓ Current branch: feature/api-v2
✓ Main branch: main (detected)
✓ Git hooks: installed

Configuration:
✓ Enabled environments: [:development, :staging]
✓ Git integration level: warning
✓ Main branch names: ["main", "master"]

Database:
✓ Migration tracking table: exists
✓ Tracked migrations: 18
✓ Orphaned migrations: 3

All systems operational! 🚀

Interactive Rollback

$ rails db:migration:rollback_orphaned
Found 3 orphaned migrations:

1. CreateApiKeys (20240116123456)
   Branch: feature/api-v2
   Author: alice@company.com
   Age: 2 hours
   
   This migration creates the api_keys table with:
   - id (primary key)
   - user_id (foreign key)
   - key_hash (string)
   - expires_at (datetime)
   
   Rollback this migration? (y/n/s/a): y
   ✓ Rolled back successfully

2. AddRateLimits (20240116123457)
   Branch: feature/api-v2
   Author: alice@company.com
   Age: 1 hour
   
   Rollback this migration? (y/n/s/a): s
   ↷ Skipped

3. CreateWebhooks (20240116123458)
   Branch: feature/api-v2
   Author: alice@company.com
   Age: 30 minutes
   
   Rollback this migration? (y/n/s/a): a
   ✓ Auto-rolling back remaining migrations...
   ✓ Rolled back successfully

Summary: 2 rolled back, 1 skipped

Cleanup Old Records

$ rails db:migration:cleanup FORCE=true
Cleaning up migration tracking records...

Records older than 30 days:
• 12 tracking records from old feature branches
• 3 records from rolled-back migrations
• 8 records from merged features

Total records to delete: 23

Cleanup completed:
✓ Deleted 23 old tracking records
✓ Database cleanup successful
✓ Tracking table optimized

Current tracking records: 45 (active development)

Best Practices

✅ Do This

Check status before switching branches

Always run rails db:migration:status before switching branches to know what you're working with.

Install git hooks for teams

Pre-push hooks prevent orphaned migrations from reaching shared branches.

Review migrations before rollback

Use the interactive rollback to understand what each migration does before removing it.

Clean up regularly

Run cleanup commands periodically to keep your tracking table optimized.

❌ Avoid This

Don't ignore orphaned migration warnings

These warnings prevent real problems. Address them before they cause issues.

Don't use --force without understanding

Batch rollbacks can be destructive. Use interactive mode first.

Don't disable in production accidentally

The gem is designed for development/staging. Don't enable in production.

Don't skip status checks in CI

Add migration checks to your deployment pipeline to catch issues early.

Real-world Tips

💡 Pro Tips from the Community

1

Use branch prefixes: Name your migration files with feature prefixes like 20240116_user_profiles_create_table.rb to make them easier to identify.

2

Coordinate with your team: Before merging large features, coordinate migration order to avoid conflicts in staging.

3

Document complex migrations: Add comments to migrations that modify existing data or have complex logic.

4

Test migration rollbacks: Always test that your migrations can be rolled back cleanly, especially in production-like environments.