# 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.

- Author: Bianca Correia
- Published: 9 Feb 2026
- Topics: ruby, rails, databases
- URL: https://biancacorreia.com/blog/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. Instead of writing SQL directly, migrations allow us to describe our database tables and columns with Ruby code.

I needed to create a `posts`table 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:

```ruby
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:

```ruby
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.
