| name | rails-migrations |
| description | Database migration patterns, reversible migrations, indexes, and conventions for this Rails codebase |
Migration Commands
rails db:create db:migrate db:seed db:reset rails console
rails db:migrate:status
rails db:rollback
rails db:migrate:redo
Migration Structure
- Migrations located in
db/migrate/ directory
- Use timestamp prefix:
YYYYMMDDHHMMSS_migration_name.rb
- Name migrations descriptively:
add_email_to_users.rb
Reversible Migrations
Creating Migrations
rails generate migration AddFieldToTable field:type
rails generate migration RemoveFieldFromTable field:type
rails generate migration CreateTableName field1:type field2:type
Common Migration Patterns
Add Column
def change
add_column :users, :email, :string, null: false
end
Remove Column
def change
remove_column :users, :email, :string
end
Add Index
def change
add_index :users, :email, unique: true
end
Add Reference
def change
add_reference :bookings, :facility, foreign_key: true
end
Add Foreign Key Constraint
def change
add_foreign_key :bookings, :facilities
end
Create Table
def change
create_table :facilities do |t|
t.string :name, null: false
t.text :address
t.timestamps
end
end
Best Practices
- Keep migrations reversible
- Use
change method instead of up/down
- Add indexes for foreign keys and frequently queried columns
- Use
null: false and foreign key constraints
- Use appropriate data types
- Include defaults when appropriate
Adding Indexes
add_index :users, :email
add_index :bookings, [:user_id, :facility_id]
add_index :users, :email, unique: true
add_index :users, :email, name: 'index_users_on_email_lower'
Foreign Keys
add_reference :bookings, :facility, foreign_key: true
add_foreign_key :bookings, :facilities
add_foreign_key :bookings, :facilities, on_delete: :cascade
When to Use Up/Down
Use up/down when change doesn't support the operation:
class ChangeUserEmailFormat < ActiveRecord::Migration[8.0]
def up
execute <<-SQL
UPDATE users SET email = LOWER(email)
SQL
end
def down
raise ActiveRecord::IrreversibleMigration
end
end
Important Notes
- Always test migrations in development
- Keep migrations small and focused
- Use
rails db:migrate:status to check status
- Never modify existing migrations after deployment
- Use
null: false for required fields
- Add indexes for performance