Migrations

Melissa Gonzalez
Adventures in Code
Published in
5 min readJul 23, 2017
For birds, a migration refers to implementing a change in location. For Programmers, a Migration refers to implementing changes to a database.

Making Changes to a Database

Changing a database in the middle of developing an app can create issues with the code. Code written with the expectation of specific field names and data types will break if the field in question is modified or deleted, or if the data type changes.

For example, some methods — such as mathematical functions — can only be used on numeric data types such as integers, floats, and decimals. If you initially set up a particular field as a string, but later decide you want to perform math on it (for example, the price of a product), you can certainly convert it to a number. However, making this change can cause issues with any code you’ve already written that assumes the price is listed as a string.

For this reason, it’s best to plan your app and map your database tables before you begin developing the app. That way, you can minimize having to go back and fix any bugs due to the changes in the database.

However, changes in the project are sometimes unavoidable, and when they do happen, you may have to perform a migration in order to implement the changes. In programming, a migration is simply refers to a change to the database.

Let’s go over how to do this in Rails!

Performing Migrations in Rails

Creating a New Model = Adding a New Table

Rails automatically generates a migration file whenever a new model is created. This makes sense since a new table must be added to the database in order to store all the information of each instance of the model.

As a review, the terminal command to create a new model might look something like:

rails generate model Products name:string price:float image:string description:string

Previous to learning about migrations, we simply ran the command rails db:migrate in our terminal immediately after creating the model in our terminal. However, now that we know and understand what a migration is, we should really be looking at our migration file prior to performing the migration command. This reduces the risk of mistakes by allowing us to catch any errors or modifications that need to be made prior to committing to the migration.

To check your migration file, navigate to your app folder and open Sublime. Within your app, the migration files are under db → migrate. If it’s a brand new app, the only thing in there should be your migration file in which you create your model (which, btw, hasn’t even been finalized yet since we haven’t done the db:migrate command).

Within the migration file, Rails has already added code to create a new table for your new model. If you added all your attributes, it also lists the name of each attribute and what type it is.

Make sure to double check this so that it’s right the first time! If anything needs to be changed, you can make edits directly into the file.

After you’ve double and triple checked that you have all the fields correct in your new database table, it’s time to commit these changes into the actual database. To do this, simply run the rails db:migrate command in your terminal (make sure you’re in the correct folder!) Now your database will have all the columns you’ve specified and is ready to add rows — also known as instances of your model!

Note that the rails db:migrate command only works on NEW migration files. Once the rails db:migrate command has been implemented on a particular migration file, the migration file can no longer be used. If any additional changes need to be made on the database, and new migration file must be created.

Making Changes to an Existing Table

In order to make changes to an existing table in your database, you need a new migration file. Luckily, Rails can generate a migration file for you if you! Simple enter the following code in your terminal:

rails generate migration DescribeChangesInTheName

This will generate a new migration in your migrate folder. The name of the new migration file will include the date and time you created the migration and your description.

Within the migration file, add code to implement your changes. Here are a few examples of some changes you may need to make, though usually it’s renaming, adding, or deleting columns, or changing the column type.

In my previous example, let’s say I want to change the price from a float to a decimal, change the description from a string to text (to allow for longer descriptions), and I also want to keep track of quantity. In order to implement the changes, I’ll add code to the migration file as follows:

You can find all available commands at: http://api.rubyonrails.org/classes/ActiveRecord/Migration.html.

BUT!! Don’t worry too much about memorizing this code! If you plan your database well, you shouldn’t have to do too many migrations!

Just like creating a new model, it’s important to double- and triple-check your migration file before running the rails db:migrate command. You don’t want to go through all that trouble making this migration file, just to turn around and have to do it again due to a typo or other mistake!

Once everything checks out, run the rails db:migrate command in your terminal, and the database should be good to go!

Debugging Code After Performing a Migration

Once you’ve performed a migration, you then have to go back and debug any code that’s broken due to the changes in your database. This is particularly important if you delete a column!

The changes I implemented in my above examples had minimal effect on my existing code, so I didn’t have to do much to debug.

However, later in class, we decided we wanted each product to have multiple images, so we created a new Image model and removed the original image attribute from the Products model. This caused us to have to find all places where Product.image was referenced and replace it with new code to reference our new image table.

Needless to say, it would have been easier if we foresaw the need for multiple images from the start and set up our database to handle that. But life is full of changes and knowing how to perform migrations will help you roll with the punches!

--

--

Melissa Gonzalez
Adventures in Code

Aspiring Web Developer. Fitness Enthusiast. Foodie. Beer Lover. Triathlete. Former Research Scientist.