What Are Migrations In Laravel?

What Are Migrations In Laravel

If you are thinking to yourself, “What Are Migrations” – this tutorial is for you. When talking about migrations in the context of Laravel, we are referring to a way to alter and update the database in a structured way. The most common database to use with PHP is MySQL, and many times, it is easy enough to create your tables manually using SQL statements. In this way, you can log in to MySQL manually, and run any of the various data definition language statements to create and design databases and tables. In the case of a content management system like WordPress, the system just runs a script and builds out all of the tables in one shot. With a dedicated framework like Laravel, developers create highly customized applications from scratch, that require a flexible way to build out the database over time. Migrations provide this and work like dedicated version control, which keeps track of all changes and updates to the database over time.


Starting With A Blank Slate

Here we have a database with no tables yet. We’re using the popular phpMyAdmin tool to view the database in a graphical way.

no tables yet

It would be easy enough to create tables right here in the graphical user interface. A drawback however is that we lose that feature of version control that is a part of migrations. In addition, with custom applications, database tables may change over time. Indeed the entire schema is subject to change, so this is why we need the flexibility of migrations. Laravel provides a nice implementation of migrations that we’ll take a look at now.


Laravel Built In Migrations

Laravel ships with two migrations already created for you. Each is a PHP file which makes use of a PHP class to create a database table and its associated fields or columns. One migration creates a users table, and the other creates a password_resets table. Let’s take a look at them now.

create_users_table.php source

create_password_resets_table.php source


Great. What Do These Files Do?

By inspecting the migration files, we can see that each has a method named up() and down(). up() is always associated with making new tables or fields in the database. Usually, every up() will also have a corresponding down(). The down() method is there to undo, or rollback, whatever the up() method does. This is for the purpose of being able to get a second shot at creating the schema of your database. If you make a mistake, you can rollback the migration, make any updates you need like a column re name or some other detail, then re run the migration.


Migrate The Database

Database migrations must be run in order to actually affect the database. With the default Laravel install, we do have these migration files, but they have not yet been run. We know this because when we connected to the database in question with phpMyAdmin, we did in fact have a blank database named homestead. Before you try to run migration files, it is important to make sure you have your database credentials configured in the Laravel environment. For this example we are using the default of a homestead database name, homestead user name, and a password of secret. In addition, the database itself must already be present in MySQL, which in this case it is as homestead.

user@localpc /c/homestead (master)
$ vagrant ssh
Welcome to Ubuntu 14.04.1 LTS (GNU/Linux 3.13.0-30-generic x86_64)

* Documentation: https://help.ubuntu.com/

System information as of Mon Mar 2 15:20:21 UTC 2015

System load: 0.97 Processes: 99
Usage of /: 5.0% of 39.34GB Users logged in: 0
Memory usage: 33% IP address for eth0: 10.0.2.15
Swap usage: 0% IP address for eth1: 192.168.33.10

Graph this data and manage this system at:
https://landscape.canonical.com/

Get cloud support with Ubuntu Advantage Cloud Guest:
http://www.ubuntu.com/business/services/cloud

Last login: Fri Dec 19 15:01:15 2014 from 10.0.2.2
vagrant@homestead:~$ cd Code
vagrant@homestead:~/Code$ cd Laravel
vagrant@homestead:~/Code/Laravel$ php artisan migrate
Migration table created successfully.
Migrated: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_100000_create_password_resets_table
vagrant@homestead:~/Code/Laravel$

In this snippet above, we have now run the migrations with the command php artisan migrate. Let’s inspect the database now and see what we get.
we have tables

Success! As a result of actually running the migrations, we now have three new tables in our homestead database. We of course have the users and password_resets tables now created, and we also have a third table of migrations. This table keeps track of when migrations are run, and is what gives us the version control aspect of using migrations. Let’s take a look at the structure of the users and password_resets tables in gui form to see how the PHP migration files above translate to actual tables in the database.

users Table

users table

password_resets Table

password_resets table

Fantastic! We can see our tables in all of their glory here. They are empty at the moment, but we can put them to use right away. You may have noticed that Laravel ships with a user authentication system implemented. Simply visit the /home route, and you will be given a chance to register as a user.

Trying To Log In Without Registering

no users yet

Register A New User

user registration

User Can Access Application

logged in

Very Nice! With this boilerplate provided for us, we can see how an authentication system works with Laravel. Now that we have actually registered a user, and logged into the application, we can examine the database. Our database tables and fields that were created as a result of running the migrations earlier should now have some data within them. As we can see below, we do in fact have a new entry in the users table for the user we registered.

we have data

Migrations With Laravel Artisan

The built in artisan tool of Laravel has many ways to work with migrations. With our new Linux Piping skills, lets find out what commands are available to us.

vagrant@homestead:~/Code/Laravel$ php artisan | grep migration

Now that we can see the commands available to us with relation to migrations, lets try some out. The first one that looks interesting is migrate:status, lets try it out.


vagrant@homestead:~/Code/Laravel$ php artisan migrate:status

This gives us a summary of what we have done with migrations so far in our application. Let’s try another one.

vagrant@homestead:~/Code/Laravel$ php artisan migrate:rollback
Rolled back: 2014_10_12_100000_create_password_resets_table
Rolled back: 2014_10_12_000000_create_users_table
vagrant@homestead:~/Code/Laravel$ php artisan migrate:status

We just did a rollback on the last database migration. This means that whatever as done the last time we ran php artisan migrate, is now undone. Well the last time we ran a migration, we created two tables and several associated fields. In addition to this we registered a user with the application. Well with this rollback, those tables, and any data in them are now history. What if we had registered 100 users with the application so far. Those users will also be lost. The takeaway is to know why you are doing a rollback before you actually do it. Now check it out. This give us a good chance to show the concept of getting a second shot at our table schema. Imagine you also want the user to have a nick name associated with their account. We can modify the migration file, then run migrations again.

Update The Migration File

Run Migrations

vagrant@homestead:~/Code/Laravel$ php artisan migrate
Migrated: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_100000_create_password_resets_table
vagrant@homestead:~/Code/Laravel$ php artisan migrate:status

Observe New Schema

updated schema


Create New Migration Files

In looking at the prior snippets of the PHP that actually creates a migration file, you may have been thinking, “Jeez, that’s a lot of code to write just to create a database table.” Fear not, as we will use automatic code generation by way of the artisan tool to create the files for us. Let’s imagine we want to create a table to hold bookmarks. Here is how we might do that.

vagrant@homestead:~/Code/Laravel$ php artisan make:migration create_bookmarks_table --create="bookmarks"
Created Migration: 2015_03_02_184309_create_bookmarks_table

It’s worth discussing the format of this command. php artisan make:migration specifies that we want to create a new migration file. The very next part is the name argument. This is a required argument to the make:migration command, and the convention is to choose a name that describes what this migration file does. In our case, we are creating a migration file that is going to create a bookmarks table. Therefore, create_bookmarks_table is a nice descriptive name of what this migration will do. The next option of –create=”bookmarks” instructs Laravel that we are creating a table with the name of bookmarks. Let’s look at what has been generated for us.

create_bookmarks_table.php source

Excellent. Laravel has provided some nice boilerplate for us to get us started. In the up() method, we see that we already have two methods to create an auto increment id field, and a timestamps field. At this point, we need to manually add the fields that we might use for holding bookmarks. We’ll need a field to hold the url, a title, and a description. Let’s add those now.

create_bookmarks_table.php source

With that update, lets run the migrations and see what we get.


vagrant@homestead:~/Code/Laravel$ php artisan migrate
Migrated: 2015_03_02_184309_create_bookmarks_table
vagrant@homestead:~/Code/Laravel$ php artisan migrate:status

new bookmarks table


Migrations For Tables You Can’t Rollback

The last thing we’ll talk about in this episode is dealing with making adjustments to tables when you can no longer rollback. When might this happen? Well, consider the example earlier where we rolled back the users table. When we did that, we lost all users that where in the table. In our case, that was only the one example user we had registered. What if we already had an application in development however, and there were hundreds or thousands of user record in that table? You don’t want to really rollback at that point, since all data contained is lost. In a case like that, you can create a new migration file for the same table. This way, you can alter a table without blowing it away entirely first.

vagrant@homestead:~/Code/Laravel$ php artisan make:migration add_tags_to_bookmarks_table --table="bookmarks"
Created Migration: 2015_03_02_195049_add_tags_to_bookmarks_table

We make the adjustment of adding our column of tags in the up() method, and the ability to undo this column with dropColumn() in the down() method. We can now run the migration.

vagrant@homestead:~/Code/Laravel$ php artisan migrate
Migrated: 2015_03_02_195049_add_tags_to_bookmarks_table
vagrant@homestead:~/Code/Laravel$ php artisan migrate:status

Like magic, we have the new column in our database now.
alter table

What Are Migrations In Laravel Conclusion

In this episode we had a good look at what migrations are in Laravel, and why it is beneficial to use them. Admittedly, when first starting to use migrations, they can seem like additional work. Once you’re up to speed with them however, they really are a great way to implement version control for your database and will actually speed up your workflow in the long run.