We are hiring

Rails Migrations in a nutshell

Mohd Sameer Author
September 07, 2020

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 (5)

Shad over 1 year ago

Thanks for saving my time.

Jason almost 2 years ago

Good article. thanks, author.

Alex almost 2 years ago

Very Helpful

Mukarram Malik almost 2 years ago


Gajendra Singh about 1 year ago

very helpful

GoodFirms Badge