Rails database migrations best practices

Maya Patel Jan 2026
3 tabs
class AddStatusToPosts < ActiveRecord::Migration[6.1]
  # Use change for automatic rollback
  def change
    # Add column without default to avoid table lock
    add_column :posts, :status, :string

    # Add index concurrently (PostgreSQL)
    add_index :posts, :status, algorithm: :concurrently
  end
end
3 files · ruby Explain with highlit

Migrations evolve database schema safely across environments. I follow strict conventions: one logical change per migration, descriptive names, reversible operations. Using change instead of up/down enables automatic rollback for most operations. For data migrations, I use reversible blocks or raise ActiveRecord::IrreversibleMigration. Adding indexes happens in separate migrations with algorithm: :concurrently for PostgreSQL to avoid table locks. I never edit committed migrations—create new ones to fix issues. Schema changes deploy before code to support zero-downtime deployments. For large tables, I add columns without defaults, then backfill in batches. Strong migration gem catches dangerous operations before production.