Rails Tips and Tricks: Migrations Cheat-Sheet

Amit Leshed
3 min readFeb 16, 2020

--

Photo by Daniel McCullough on Unsplash

First things first, why do we even need migrations?

Migrations are a convenient way to alter your database schema over time in a consistent and easy way. They use a Ruby DSL so that you don’t have to write SQL by hand, allowing your schema and changes to be database independent.

Without further ado, let’s get right into it:

Creating a table

This one is an alternative for “rails g model product”, but since we already covered that in the last article, I figured why not creating a model with a plain migration? Type in your terminal:

$ rails generate migration CreateProducts name:string in_stock:boolean

This will magically generate the following migration (can be found in db/migrate):

class CreateProducts < ActiveRecord::Migration[6.0]
def change
create_table :products do |t|
t.string :name
t.boolean :in_stock
end
end
end

Dropping a table

For this one there’s no magic generator so we’ll have to write the migration ourselves, no worries though, it’s really easy:

rails generate migration DropTableProducts

will generate:

class DropTableProducts < ActiveRecord::Migration[6.0]
def change
end
end

All that’s left is to add “drop_table :products” so the code looks like so:

class DropTableProducts < ActiveRecord::Migration[6.0]
def change
drop_table :products
end
end

Add and remove columns

Okay, what if we have an existing table but we just need to add or remove a column?

$ rails generate migration AddPriceToProducts price:integer

will generate:

class AddPriceToProducts < ActiveRecord::Migration[6.0]
def change
add_column :products, :price, :integer
end
end

Easy right? you just have to define the :table, :column and :type.

Repeat the same process for removing a column:

$ rails generate migration RemovePriceFromProducts price:integer

will generate:

class RemovePriceFromProducts < ActiveRecord::Migration[6.0]
def change
remove_column :products, :price, :integer
end
end

Change existing column

What if we already have a column but we need to change it’s existing name or type? No biggie, run:

$ rails generate migration ChangeProductsPrice

will generate:

class ChangeProductsPrice < ActiveRecord::Migration[5.0]
def up
change_table :products do |t|
t.change :price, :string
end
end
def down
change_table :products do |t|
t.change :price, :integer
end
end
end

up” is the changes we want to occur, “down” is what we want to get rid of.

Add and remove foreign key

$ rails generate migration AddUserRefToProducts user:references
class AddUserRefToProducts < ActiveRecord::Migration[6.0]
def change
add_reference :products, :user, foreign_key: true
end
end

removing a foreign key:

$ rails generate migration RemoveUserRefFromProducts user:references

will generate:

class RemoveUserRefFromProducts < ActiveRecord::Migration[6.0]
def change
remove_reference :products, :user, null: false, foreign_key:true
end
end

Rollbacks

Rollbacks are useful when you have no data or no problem reversing the schema. Every time you’ll use “rails db:rollback” the schema will reverse the last migration, you can also reverse a few migrations by calling “rails db:rollback STEP=3

Don’t forget to run “rails db:migrate” at the end of each operation to actually change the schema!

I really encourage you to dive deeper and check out the Rails Guides, thanks for reading!

--

--