Defining Database Schema in Rails Using Migrations

Rails migrations provide a powerful way to define and evolve your database schema over time. Understanding how to effectively use migrations is crucial for maintaining a healthy database structure. For more on migrations, check out our guide on explain concept migrations rails how they work.

Understanding Rails Migrations

Migrations are version control for your database schema, allowing you to define changes incrementally and maintain consistency across different environments. For more on Active Record features, see our guide on rails active record key features.

Creating a Migration

Generate a new migration using the Rails command line:

bash
1rails generate migration CreateUsers
2

For more on different types of migrations, check out our guide on rails different types of data migrations.

Defining Schema Changes

Use Rails' migration DSL to define schema changes:

ruby
1class CreateUsers < ActiveRecord::Migration[6.1]
2 def change
3 create_table :users do |t|
4 t.string :name, null: false
5 t.string :email, null: false
6 t.text :bio
7 t.integer :age
8 t.timestamps
9
10 t.index :email, unique: true
11 end
12 end
13end
14

For more on schema management, see our guide on db schema rb purpose.

Common Migration Operations

Adding Tables

Create new tables with appropriate columns and constraints:

ruby
1class CreateProducts < ActiveRecord::Migration[6.1]
2 def change
3 create_table :products do |t|
4 t.string :name
5 t.text :description
6 t.decimal :price, precision: 10, scale: 2
7 t.references :category, foreign_key: true
8 t.timestamps
9 end
10 end
11end
12

For more on database design, check out our guide on database schema design strategies for performance.

Adding Indexes

Optimize query performance with appropriate indexes:

ruby
1class AddIndexesToProducts < ActiveRecord::Migration[6.1]
2 def change
3 add_index :products, :name
4 add_index :products, [:category_id, :name]
5 end
6end
7

For more on indexing, see our guide on handle database indexes rails migrations.

Modifying Columns

Change existing columns with proper data type conversions:

ruby
1class ModifyUserColumns < ActiveRecord::Migration[6.1]
2 def change
3 change_column :users, :email, :string, null: false
4 add_column :users, :status, :string, default: 'active'
5 remove_column :users, :temporary_field
6 end
7end
8

For more on performance considerations, check out our guide on best practices for performant database migrations.

Best Practices

1. Keep Migrations Reversible

Use the change method when possible, or define both up and down methods:

ruby
1class AddUserSettings < ActiveRecord::Migration[6.1]
2 def up
3 add_column :users, :settings, :jsonb, default: {}
4 end
5
6 def down
7 remove_column :users, :settings
8 end
9end
10

For more on rollbacks, see our guide on rollback migrations in rails guide.

2. Use Appropriate Data Types

Choose the right data type for each column:

ruby
1create_table :orders do |t|
2 t.decimal :amount, precision: 10, scale: 2 # For money
3 t.datetime :processed_at # For timestamps
4 t.boolean :completed, default: false # For flags
5 t.jsonb :metadata # For JSON data
6end
7

3. Add Database Constraints

Enforce data integrity at the database level:

ruby
1add_foreign_key :orders, :users, on_delete: :cascade
2add_check_constraint :products, "price >= 0", name: "price_must_be_positive"
3

For more on query optimization, see our guide on rails database indexes improve query performance.

Related Resources

Migration Basics

Schema Management

Performance and Best Practices

Conclusion

Defining database schema in Rails using migrations is a powerful way to manage your application's data structure. By following these best practices and understanding the available tools, you can create maintainable and efficient database schemas that evolve with your application's needs.

Suggested Articles