Skip to content

What I Learned About Active Record Migrations in Ruby

In this exercise, I learned how to use Active Record migrations to build the structure of a database using Ruby.

2 min read

In this exercise, I learned how to use Active Record migrations to build the structure of a database using Ruby. Instead of writing SQL directly, migrations allow us to describe our database tables and columns with Ruby code.

I needed to create a poststable that can store links shared by users. The table needed a title, a URL, and timestamps.

I also learned that migrations are only used to change the structure of the database, not the data inside it.

Migration files must follow a specific naming format:

yyyymmddhhmmss_migration_name.rb

For example:

20260202152200_create_posts.rb

The timestamp in the filename is important because it tells Active Record which migrations have already been run and which ones still need to run.

Creating the Posts Table#

To create the posts table, I wrote the following migration:

class CreatePosts < ActiveRecord::Migration[8.1]
def change create_table :posts do |t|
t.string :title
t.string :url
t.timestamps
end

This migration creates: a title column, a url column, created_at and update_at column using t.timestamps.

The timestamp columns are useful because they record when a post is created and when it is updated.

After writing the migration, I ran: rake db:migrate. Then I checked the database with: sqlite3 db/development.sqlite3 .schema.

I noticed there were more tables than just my posts table. These extra tables are created by Active Record and are used to keep track of migrations and manage the database internally.

Updating the Posts Table#

Next, I created another migration to update the posts table. I added a new column called votes.

I created a new migration file with a new timestamp and wrote the following code:

class AddVotesToPosts < ActiveRecord::Migration[8.1]
def change add_column :posts, :votes, :integer, default: 0

This migration added a votes column, with a type integer and a default value of 0.

his means a post starts with zero votes when it is created.

I then ran the migration again: rake db:migrate

Now the posts table contains title, url, created_at, updated_at and votes.

In this exercise, I learned how to use Active Record migrations in Ruby to create and change the structure of a database. I created a posts table for a Hacker News clone with columns for a title, a URL, and timestamp fields for created_at and updated_at. I also learned that migration files must be named using a timestamp so Active Record knows which migrations to run and in what order. After running rake db:migrate, I checked the database schema and saw extra tables created by Active Record, which showed me that it also manages internal information about the database. Finally, I wrote another migration to update the table by adding a votes column with a default value of 0, which helped me understand that migrations are used to change the database structure, not to insert data.