Database Migrations
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 |
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 thestudents
table, name itAddFirstNameToStudents
.
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:
class AddFirstNameToStudents < ActiveRecord::Migration[5.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
...
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.
$ rails db:migrate:status
Status Migration ID Migration Name
--------------------------------------------------
up 20161212101030 Create books
$ rails db:rollback
$ 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.
References: