Rails Migrations in a nutshell

Screenshot 2020 09 07 at 7.36.40 pm
Mohd Sameer Author
September 07, 2020
Migration thumb

Migrations are the perfect way for you to create and modify your database in an organized and in a well-structured manner. One of the main advantages of migrations is that we don’t have to write SQL queries since migrations provide you an easy Ruby DSL to Create/Change your table. 

Migrations allow us to create tables, add or remove columns, and add indexes on columns. Whenever a migration is generated through command it is stored in db/migrate folder of your Rails app directory. 

In this post, you'll be learning about the following point of migrations

Creating a table through migrations

This how a table is created using migrations. Through the following command, we are generating a Post table within our database with two columns Title and Content. 

Remember to use the capitalized name for the table/model name.


$ rails g migration CreatePost title:string content:text


This can also be done as 


$ rails g model Post title:string content:text

Both commands would generate the same file with a title consisting of timestamped and class name following by the ruby extension. 20200715064057_create_posts.rb 

class CreatePosts < ActiveRecord::Migration[5.1]
  def change
  create_table :posts do |t|
    t.string :title
    t.text :conent


The next step is to run

rails db:migrate


Upon running rails db:migrate   a table called posts with a string column called title and a text column called content would be added to db/schema.rb. An integer column called id
and a column timestampd will also be added implicitly, id is the default primary key for all Active Record models and  timestamp adds two columns, created_at and updated_at to the database schema. These two columns are automatically managed by ActiveRecord if their record exists.

*Note - Running rails db:migrate   is mandatory every time a rails migration is added


Usage of ‘text’ or ‘string’  while generating migrations?

As a general rule of thumb, use :string for short text input (username, email, password, titles, etc.) and use :text for longer expected input such as descriptions, comment content, etc.


Migration to create a table with reference columns

The need for creating a table like this arises when multiple records in a table are associated with multiple records in another table. For example, there's a Post table and a Tag table. Both tables can have multiple records associated with each other so we need to have a bridge table, PostTag.

$ rails g migration CreatePostTag post:references tag:references


This will generate the following code in a migration file

class CreatePostTags < ActiveRecord::Migration[5.1]
  def change
    create_table :post_tags do |t|
      t.references :post, foreign_key: true
      t.references :tag, foreign_key: true


When we reference a model, index on the foreign_key is automatically created.

Changing table through migrations

Rename a table with a single Rails migration

I have a Post table within my database but for reason, I want to change it to Article. Here how you can do it; 

We need to generate a migration through the following command

$ rails generate migration RenamePostToArticle



This will give us an empty migration file, we can modify it ourselves with the following code

class RenameOldTableToNewTable < ActiveRecord::Migration[5.1]
def change
rename_table :posts, :articles #Tables name should be pluralized

Run rails db:migrate and you are good to go😎


Let's learn to drop a table from the database.

Through this command, we are generating a migration to remove the Post table including its columns from the database.

$ rails generate migration DropPostTable


The above command would generate an empty migration file, we can edit it with the following code;


class DropPostsTable < ActiveRecord::Migration[5.1]
def up
drop_table :posts

def down
raise ActiveRecord::IrreversibleMigration

Run rails db:migrate to disappear the Post table from your database.

Rollback a migration

Running plain rails db:rollback command would revert the lastest migration changes to the database.

But if you want to revert a specific migration you can do it with the following command.


$ rake db:migrate:down VERSION=20200715064057


This will revert the following migration file: db\migrate\20200715064057_create_posts.rb  Here migration file is identified by its timestamp.

another way of rollback a migration is to use the STEP argument with rails db:rollback command. 

Here is how you can execute this;

$ rake db:rollback STEP=2

In this case, we are defining the number of migration files we want to roll back in a chronological manner.


Command to Add a column to an existing table

We sometimes need to add more columns to our table for our development requirements. The most efficient way of adding a column is to generate a migration. 

We need to add a publish column to our existing Post table. We can do by running the following command;


$ rails g migration AddPublishToPost publish:boolean


It would give us the following code in the migration file


class AddPublishToPost < ActiveRecord::Migration[5.1]
  def change
    add_column :posts, :publish, :boolean

Assigning default value to a column

We can assign a default value to a column by modifying the above file with the following code.

class AddPublishToPost < ActiveRecord::Migration[5.1]
  def change
  add_column :posts, :publish, :boolean, default: false


We just added a default: false  key-value pair to make the publish always default upon initializing a new record.

A good way to Rename a column.

Let's change the Post publish  column to status. To make this change we need to have the following migration generated.

$ rails g migration ChangePublishToStatus

This will give us a migration file with an empty change method. We need to modify the migration file like this;

class ChangePublishToStatus < ActiveRecord::Migration[5.1]
  def change
 rename_column :posts, :publish, :status

It will rename the column but keeps the type and content remains the same.


Change Column

Let's learn to change a column type in the most simple and reliable way. In this example, I want to change the publish  column type from boolean to integer  

Run the following command to generate a migration.

rails g migration ChangePostPublish

Edit it like the following file;

class ChangePostPublish < ActiveRecord::Migration[5.1]
  def change
   reversible do |dir|
    change_table :posts do |t|
      dir.up   { t.change :publish, :integer}
      dir.down { t.change :publish, :boolean }

It will change the column type.

Remove a Column from table

Here how you can remove the column from a table. Let's take an example of Post table, we want to remove the view column from it. 

Create a migration using the following command

rails g migration RemoveViewFromPost view:integer


It will generate a migration file with the following code. we don't need to modify it.

class RemoveViewFromPost < ActiveRecord::Migration[5.1]
  def change
  remove_column :posts, :view, :integer

Running rails db:migrate would extract and remove the view column from the Post table.

Reset database

$ rake db:reset db:migrate


$ rake db:drop db:create db:migrate

Seeding databases

Run rails db:seed to create a record of Post using seed.

Creating multiple records with single rails db:seed command.

iterate over the Post using Ruby Times Loop. Our db/seed.rb file would look like this;

You can also run the seed command to populate the database at the time of creating a database.

$ db:create db:migrate db:seed

Please share this article if you found this useful. I would write more such articles for you to simplify your rails learning.


Comments (3)

Av 8
Jason 15 days ago

Good article. thanks, author.

Av 9
Mukarram Malik 15 days ago


Av 0
Alex 15 days ago

Very Helpful