When I first started with Laravel, the migrations looked easy and a very good idea. As I progressed, it seemed like a great idea, but I was always running into trouble with them. Running “migrate” was seldom straight forward, “rollback” and “refresh” almost never worked. Especially when it was someone else’s migrations that you are trying to run. It worked on one setup, threw errors on the others. It was not until I gave some time to understand the underlying concept that I could use them efficiently and utilize their full potential.

In this article I would like to share my knowledge on Laravel migrations, that could make a first-time Laravel developer’s life easy. The list is in no way complete, just few points off the top of my head.

Understand “migrate” and “migrations” table

To understand how migration works, you have to understand the “migrations” table. It is actually quite simple. There are only 2 columns in the table (apart from the auto-incremented id) “migration” and “batch”.

When you run “php artisan migrate” for the first time, for each migration file that runs, a row is inserted in the “migrations” table with the name of the file in “migration” column with a “batch” value 1.

The next “migrate” runs new migrations, which have been added after the first “migrate”, i.e. with names not in the “migrations” table, and insert rows with “batch” value 2, so on and so forth.

When you run –

“php artisan migrate:rollback” the last batch of migration is rolled back, i.e. the “down” method of the migrations are called. And the corresponding rows are deleted from the table.

“php artisan migrate:reset” rollbacks all the migrations, deletes all the rows in the table.

“php artisan migrate:refresh” resets and re-runs all the migration files.

And also, the “migrate” runs files sorted by names in the ascending order, “refresh” and “rollback” in the descending order. To maintain the order, “php artisan make:migration” creates migration files with timestamp appended to the name you provide. Try remembering the very helpful options provided for the “make:migration” command. Will make life much easier for you.

Create new migration to make changes

Always create new migrations to alter a table. Especially if you are working in a team and you have checked in your migration to the repository. It is very irritating to update the code and get a broken migration. But even if you are not working in a team, always creating new migrations to make all changes is a good idea.

For example, if you want to add ACL to you application. You want to add a “roles” table. And a foreign key column “role_id” to the “users” table. You add a create migration for the “roles” table and change the “users” table migration to add the foreign key. And when you run the migration – of course you will get an error – saying that the foreign key reference table does not exist. So the proper way is to create another migration to add the “role_id” foreign key to the “users” table, that would run after the “roles” table has been created.

There are 2 ways you can go creating migrations –

  1. By table name
  2. By functionality

Like in the above example, you could have created 2 migrations “create_roles_table” and “add_role_id_to_users_table”. Or you could have created only one “add_scheme_for_acl”. It’s your choice, whatever feels comfortable.


  • Before modifying a column, be sure to add the “doctrine/dbal” dependency to your “composer.json” file.
  • When creating a table for the first time, it’s fine to have some columns be not nullable, but when altering and adding a column, even though the table is empty, “migrate” will throw an error. The solution is to set a default value to the column.

Don’t ignore the “down” method

I have often seen, when creating migrations, developers concentrate on the “up” method. During create tables, the placeholder code generated by artisan is enough. But when you are altering tables, adding/renaming columns, creating relations almost always the “down” method is ignored. And this will throw errors and leave you with a messed up schema if one day you need to refresh or rollback your migration, and you will surely need to.

So I always suggest that before checking your migration in – always test your migration with both “migrate” and “rollback” commands.

Understanding Laravel Migration and sticking to these few practices, you will find it is a extremely useful tool to manage your schema, especially for a multi-user team.

Understanding Laravel Migrations : Dos and Don’ts
Tagged on: