Rails Migrations in a Nutshell

Rails migrations in a nutshell

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

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

In this post, you'll learn about the following points of migration

  • create_table

  • change_table

  • drop_table

  • DB:rollback

  • add_column

  • rename_column

  • change_column

  • remove_column

  • DB: reset

  • DB: seed


Creating a table through migrations

This is 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 a timestamp and class name followed 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
 
      t.timestamps
    end
  end
end

 

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, it 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

      t.timestamps
    end
  end
end

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 this reason, I want to change it to Article. Here is 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
end
end


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
end


def down
raise ActiveRecord::IrreversibleMigration
end
end


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

Rollback a migration

Running plain rails db:rollback the command would revert the latest 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 this 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
  end
end


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
  end
end

 

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
  end
end

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 }
      end
    end
  end
end

It will change the column type.

Remove a Column from the table

Here is how you can remove the column from a table. Let's take an example of the 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
  end
end


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 Posts using seed.

Creating multiple records with a 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.



Read More: Python and Django: Build Powerful Web Applications
Ruby Vs Python: Which will You Choose for Your Next Projects?



Comments (5)
Av 2 Shad
about 3 years ago
Thanks for saving my time.
Av 8 Jason
over 3 years ago
Good article. thanks, author.
Av 0 Alex
over 3 years ago
Very Helpful
Av 9 Mukarram Malik
over 3 years ago
great
Av 7 Gajendra Singh
almost 3 years ago
very helpful

Leave Your Comment Here

About Adware Technologies

As a team of dedicated professionals, we are driven by our passion for technology and our commitment to delivering excellence. With our expertise in web development and mobile development, we are poised to help our clients achieve their business goals and thrive in the ever-evolving digital landscape.

Contact us today, and let's embark on a collaborative journey towards success. Together, we'll turn your vision into reality and create a lasting impact in the digital world.

Good firms Clutch
Contact Us
×
Got a project to discuss or need advice?
Let's talk about it.