SwitchUp SwitchUp Ranked Best Coding Bootcamps 2025

Database Migrations

Written in Ruby on Rails
updated on 10 Jan 2023

Migrations are a convenient way to alter your database schema over time in a consistent and easy way. Traditionally, you have to write raw SQL to modify the database schema. In Rails, you only need to write Ruby code to do the migrations.

You can think of each migration as being a new version of the database. A schema starts off with nothing in it, and each migration modifies it to add or remove tables, attributes and other modifications. Active Record tracks your schema with a history timeline, enabling it to go back and forth to any versions of your schema. Active Record will update your db/schema.rb file to match the up-to-date version of your database schema.

Data Types

In a relational database, such as PostgreSQL and SQLite3, you have many data type to choose from for your attributes. Primarily, we have data types that are designed to store numbers, text and dates.
Below is a list of commonly used data types for database attributes:

| Data Type | Description | |--------------|----------------------------------------------------------------------------------------------------------------------| | string | unlimited length of text (depending on the database) | | text | unlimited length of text (depending on the database) | | integer | whole numbers (i.e. 1, 2, 3, 4, 5), and NOT numbers like 2.73 | | float | decimal numbers with floating point precision (not precise enough if you are dealing with banking records and money) | | decimal | decimal numbers with precision. Use these for math that needs to be accurate and exact | | boolean | true / false | | date | a date (year, month, day) | | time | a time (hours, minutes, seconds) | | datetime | both date and time | | timestamp | for the purpose of Rails, [timestamp and datetime are the same](https://stackoverflow.com/questions/3928275/in-ruby-on-rails-whats-the-difference-between-datetime-timestamp-time-and-da) | | binary | images, movies, and other files in their original, raw format in chunks of data called BLOBs (binary large objects) |

Using the change Method

To create a migration, use $ rails generate migration <Name of Migration>. To add a column author_id to the books table, we can use $ rails generate migration AddAuthorIdToBooks

Make sure your migration file name makes semantic sense. For example, if you are trying to add first_name to the students table, name it AddFirstNameToStudents.
After you create an empty migration, you can use a lot of different methods to modify the database schema.

Here's a list of methods you can use:

| Method | Description | |----------------|--------------------------------------------------------------------------------------| | add_column | add a new column in a table | | add_index | create an index in a table | | add_reference | add a new relationship with another table | | add_timestamps | add two columns `created_at` and `updated_at` with _datetime_ data type | | create_table | create a new table | | drop_table | remove table from database schema; all record will be gone | | remove_column | remove a column from a table; all records will gone for that specific column |

For example, to add first_name with string data type to books table, you can do:
language=>ruby class AddFirstNameToStudents < ActiveRecord::Migration[6.0] def change add_column :books, :first_name, :string end end
To index the attribute first_name, you can do
What's indexing? Indexes are used to quickly locate data without having to search every row in a database table every time a database table is accessed
language=>ruby ... def change add_index :books, :first_name end ...

Rollback

Migration's job is to modify the current table schema. Another common task is to rollback the last migration (to revert the changes). For example, if you makes a mistake in your migration file and intend to fix it, you can rollback / revert the previous migration using $ rails db:rollback. You can also track down the exact version number associated with the previous migration.
language=>sh $ rails db:migrate:status Status Migration ID Migration Name -------------------------------------------------- up 20161212101030 Create books

language=>sh $ rails db:rollback

language=>sh $ rails db:migrate:status Status Migration ID Migration Name -------------------------------------------------- down 20161212101030 Create books
You can see that the status went from "up" to "down" after we rollback the previous migration.

Remember, when you run $ rails db:rollback, it will only rollback the previous ONE migration. But, when you run $ rails db:migrate, it will migrate ALL the migrations that aren't "up" yet.
What if you want to rollback more steps at once? $ rails db:rollback STEP=3 will revert the last 3 migrations.
What if you want to rollback to an exact version? $ rails db:rollback VERSION=x will revert the exact migration specified by the version number.

Migration files must be in ascending orders

What happens if your migration files are ordered like the following:
1. add some columns to the user table
2. create the user table

Here's the scenario:

1. the database is currently completely empty
2. the database connects to your rails app
3. the models in your app need to be consistent with the database
4. now the database is still empty, so even if you edit your model, nothing is going to work
5. so let's work on the database first
6. how do you modify the database? you create migration files and run rails db:migrate
7. now assuming you have no migration files, and you run rails db:migrate...nothing happens
8. so let's add a migration file
9. let's try to add a column to a user table, run rails db:migrate ... error occurs...because user table doesn't exist in the database yet
10. the database at this point is still completely empty...nothing works
11. let's add the user table first... make sure you delete the previous "add a column to a user table" file, because rails db:migrate runs sequentially

The correct steps would be:

1. database is empty
2. add User table to database
3. add columns to User table in database
4. run rails db:migrate to execute your instructions to the database
5. database is no longer empty

References:
  1. ActiveRecord Migrations

Trusted by

Students and instructors from world-class organizations

Imperial College London
Carnegie Mellon University
City University of Hong Kong
Hack Reactor
Cisco Meraki
University of Oxford
Swift
Bazaarvoice
Waterloo
Uber
AtlanTech
Tumblr
Boston College
Bombardier Aerospace
University of St. Andrews
New York University
Minerva Schools at KGI
Merrill Lynch
Riot Games
JP Morgan
Morgan Stanley
Advanced Placement®
Google
KPMG
The University of Hong Kong
University of Toronto
SCMP
Moat
Zynga
Hello Toby
Deloitte
Goldman Sachs
Yahoo
HSBC
General Assembly
Tesla
McGill University
Microsoft

Join the upcoming Cohort #103

Enroll for July 7th, 2025