Rails Migration — Part 1
Generating migration files.
Table of Contents
Migration is one of the features of Active Record which enables us to modify our table in database in a structured and organized manner.
As I covered in the Active Record article, migrations allow us to modify or create the transformations of a database in Ruby, which means we don't have to worry about implementing SQL for the most part, however, for certain database features, we would require to use SQL.
This topic is very vast to be covered in a single article. So I have divided it into 3 parts, in this article (Part 1) we will cover:
- How to generate tables and declare their attributes with the custom data type.
- Understanding migration files.
- Methods like
create_tableand special helpers like
- Destroy migration.
To generate a table named
age as its attribute in the database, we give a migration like this in CMD:
rails generate model Author name:string age:integer
This is called a model generator and contains instructions for creating a relevant table. We specify the name of a table we want to create and attributes of it along with its data type.
After running the following command, we get the following output:
It has created 4 files for us:
- Migration file 👉
- Corresponding model file 👉
- The other 2 files are corresponding test files of
Migration File Name Format
The above command invoked Active Record to run the migration and created a migration file automatically in
db/migrate directory in this format :
YYYYMMDDHHMMSS represents a UTC of when migration was generated followed by an underscore followed by migration name,
The migration file name will always be in the format of snake_case whereas the table name will be in CamelCase, So for the table name
Author, its corresponding file will be
Product, its corresponding file will be
create_product and so on.
A look at the migration file:
CreateAuthors class has been generated for us which inherits from the
Migration class of the
ActiveRecord module. This means we have all of the instance methods available to use from the
In the scope of
change method, the
create_table method takes 2 arguments, first, the name of the table in the database,
authors and second, takes a block of attributes and its data-type as
key:value pairs. The
t.timestamps method is implicitly added by Active Record which will generate 2 columns,
updated_at along with the primary key,
A foreign key is an attribute in a table where for each of its intsances it links to a row of another table.
These are used in a table whose in a relationship with another table so that each instance of it can link to anyone instance of the other table with its primary key. We need to explicitly define it as it isn’t declared for us implicitly.
Let's see an example of
We create another table
books so that each book is linked to an author from the
rails g model Book title:string authors:references
g is short for
references given to the table of
authors, this will create a column or an attribute :
- with a name formatted as
‘table_name’_id, in our case
- which is our
For this reason,
referencesmethod is also called a special helper method because it provides a simple shortcut to multiple functionality.
Running above migration will generate the following migration file:
references method supports the following options,
foreign_key. So if you want to set
true, you can declare it as:
t.references :authors, foreign_key: true, index: true
We can also specify comments to the table and its attributes explicitly in the migration file which would help people understand the data model.
class CreateAuthors < ActiveRecord::Migration[5.2]
create_table :authors, comment: 'Authors who have published best-selling books' do |t|
t.string :name, comment: 'Name of Author'
:comment, is declared as
key:value pair, where value contains the description of it. These are stored in the database itself. We can view these comments when running the migration, or in
db/schema.rb file, or with Database Administration Tools such as MySQL Workbench or PgAdmin III.
:comment is currently only supported by MySQL and PostgreSQL.
An alternate way to create a table
rails g migration CreateBook title:string authors:references
Our migration name here is
CreateBook. Whatever migration name we declare, that name will be set as our migration class name.
Create keyword followed by the singular table name. This will tell Active Record to invoke the
create_table method and create the following attributes with the column-type specified.
The difference between this migration and the earlier
model migration is that this migration only creates a migration file and not the corresponding model file.
Another difference is that this migration doesn’t implicitly create the
timestamps method in the migration file. So running this migration will not create
updated_at columns. To avoid this, we would need to explicitly mention the
t.timestamps method under the scope of the
timestamps method is also another special helper method.
However, the primary key will be implicitly created with the default name as
Setting unique to an attribute
rails g model Book title:string:uniq
unique to the
title attribute invokes
add_index method, so not only our attributes’ values will be unique but its
index is also set to
What is Index?
If you have a large database with millions of records and high traffic, the responses become slow, so extracting data becomes more time-consuming as records increase. If we’re extracting the same attribute, again and again, for example, email or username or a foreign key, using
index to it would make operations faster & efficient as queries would be easily searchable because
indexcreates a copy of that attribute and sorts them in alphabetical order.
For more info on this, refer to this post.
It does not allow duplicate values in the same column/attribute in a table.
Active Record supports the following database column types:
You may use a type that is not in this list as long as it is supported by your database, for example, using
polygon in MySQL. But this won’t be database agnostic and should usually be avoided.
This article gives a detailed explanation of each column type and what column types are available to use for different databases.
Delete Migration Files
Now let’s see how to destroy migration files, assuming we have a model class named
rails destroy model Book
Running via Spring preloader in process 33047
All 4 files that were created when running
generate, will be deleted with
If you have already run the migrations on it, you need to manually rollback those migrations that created or updated this table in anyway, so that it updates the schema accordingly and we don’t run into errors when running
destroycommand just deletes the files that generated when
migrationwas ran and not the table in database, there's no coming back from it!
After creating migration files, in Part 2 we will look into how to generate a corresponding table of it in the database.
Part 2: Executing Migration Files
What are indexes? And how to add them to your Rails app?
When dealing with databases, the subject of indexing must inevitably come up. And with any rails app, you are most…
Rails ActiveRecord Data Types
I am usually curious to know about Data Types for ActiveRecord, but the Active Record Migration documentation itself does…
Rails Generators Cheat Sheet
As a beginner of Rails, I often get confused about what generator generates what and the syntax of these commands…