Tip
Mighost is the recovery engine behind the ghost-migration features of
railbow, which wraps it in rich, colorful
db:migrate:status output. If you want beautiful Rails CLI output and ghost recovery
in one step, you probably want to install railbow directly — it detects mighost and
uses it automatically.
The Problem
When working with Rails migrations across git branches:
- You run migrations on a feature branch
- Switch back to
main - Run
db:migrate- Rails dumps schema including changes from the other branch - You can't rollback because the migration files don't exist in current branch
Usual workaround: Switch to the other branch, rollback, switch back. Tedious.
The Solution
Mighost automatically captures migration file contents when they run, enabling rollback even when the original file is not present. It uses a 3-tier recovery strategy:
- Stored snapshots — captured at migration time into a local SQLite file
- Git history — searches across all branches
- Worktree recovery — finds files in other git worktrees
Installation
Add to your Gemfile:
gem 'mighost', group: [:development, :test]Then run:
bundle install
rails generate mighost:installAdd .mighost.sqlite3 to your .gitignore.
Requires Ruby >= 3.1 and Rails 6.1–8.1.
Usage
Check for orphaned migrations
rails mighost:statusRollback orphaned migrations
# Interactive (with confirmation)
rails mighost:rollback
# Force (no confirmation)
FORCE=1 rails mighost:rollback
# Specific version
rails mighost:rollback VERSION=20240115123456Scan existing migrations & git history
If you install Mighost on an existing project:
rails mighost:scanAll commands
| Command | Description | Options |
|---|---|---|
mighost:status |
Show orphaned migrations |
DEBUG=1, SHOW_DISMISSED=1
|
mighost:rollback |
Rollback orphaned migrations |
VERSION=x, FORCE=1
|
mighost:scan |
Capture migrations + search git | RESCAN=1 |
mighost:list (ls) |
List stored migration records | LIMIT=N |
mighost:dismiss |
Hide migrations from status |
VERSION=x, VERSION=a..b, OLD=1
|
mighost:undismiss |
Restore dismissed migrations | VERSION=x |
mighost:dismissed |
List dismissed migrations | |
mighost:cleanup |
Remove stale records | FORCE=1 |
mighost:help |
Show command reference |
Version ranges
VERSION=20240115123456 # Single version
VERSION=20240110..20240120 # Inclusive range
VERSION=20240110.. # From version onwards
VERSION=..20240120 # Up to versionConfiguration
# config/initializers/mighost.rb
Mighost.configure do |config|
# Path to SQLite file (relative to Rails.root)
config.storage_path = ".mighost.sqlite3"
# Auto-capture on migrate
config.auto_capture = true
# Store git metadata
config.store_git_metadata = true
# Enable/disable (disabled in production by default)
config.enabled = !Rails.env.production?
endRich Output with Railbow
By default, Mighost outputs plain, uncolored text. For rich, colorized output with tables, emojis, and git enrichment, use the railbow gem:
gem 'railbow'Railbow automatically detects Mighost and enhances its output.
Public API
Mighost exposes a stable API for programmatic access:
# Detect orphaned migrations
Mighost::API.orphaned_migrations # => [OrphanedMigration, ...]
# Find snapshots
Mighost::API.find_snapshot("20240115123456") # => Snapshot or nil
Mighost::API.find_or_recover_snapshot("20240115") # => Snapshot (with git/worktree fallback)
# Scan and recover
Mighost::API.scan!(rescan: false) # => {captured:, git_recovered:, ...}
# Rollback
Mighost::API.rollback_version!("20240115123456") # raises on failureUI Adapter
Mighost uses a pluggable UI adapter for output. Replace it to customize formatting:
# In your railtie or initializer:
Mighost.ui = YourCustomUI.newThe adapter must implement: render_orphans, render_records, render_recoverable_list, render_scan_details, render_scan_results, render_dismiss_preview, render_dismiss_remaining, render_dismissed_list, confirm?, confirm_each?, confirm_dismiss?, success, error, warning, info, hint. See Mighost::PlainUI for the reference implementation.
How It Works
-
Capture: When you run
db:migrate, Mighost hooks intoActiveRecord::Migratorand stores the migration file content along with git metadata (branch, SHA) in a local SQLite file. -
Detect:
mighost:statuscomparesschema_migrationstable with actual migration files to find orphans. -
Recover: For missing files, Mighost searches stored snapshots, git history (all branches), and other git worktrees.
-
Rollback: Writes recovered content to a temp file, loads it, calls the
downmethod, then removes the version fromschema_migrations.
Limitations
-
Irreversible migrations: If the migration raises
ActiveRecord::IrreversibleMigration, Mighost can't help. - Model dependencies: If your migration references models/classes that don't exist in the current branch, the rollback may fail.
- Manual SQL changes: If someone manually modified the database, rollback might not work correctly.
- Trust: Recovered migration code (from snapshots, git history, or worktrees) is executed with the same trust as your own migrations — it is code from your repository, run by you.
Contributing
Bug reports and pull requests are welcome on GitHub. Run bundle exec rake (specs + standardrb) before submitting.
License
MIT License. See LICENSE.