This is the continuation of my previous article where we talked about creating a multi-tenant app using Laravel and Postgres. I recommend you to read that article before moving forward with this one.

Since our multi-tenant app is ready, we want to utilize Laravel’s console commands to handle our migrations. In this article, we will see how we can extend Laravel’s migration implementation to gracefully handle migrations for all schemas of our multi-tenant app.

Overview

Laravel provides easy console commands within migrate namespace to handle migrations. eg:

$ php artisan migrate

$ php artisan migrate:rollback

...

But, as you might have noticed, these commands will only run migrations in default schema, which in our case needs to be run for all schemas. We will extend commands provided by Laravel to add 2 new options:

--all

--schema=[SCHEMA]

So, we will be able to:

# Run migrations in all available schemas.

$ php artisan migrate --all # Run migrations in given schemas.

$ php artisan migrate --schema=th,vn,ph # Rollback migrations in all available schemas.

$ php artisan migrate:rollback --all # Rollback migrations in given schemas.

$ php artisan migrate:rollback --schema=th,vn,ph

I am using Laravel 5.5 and PostgreSQL 9.5 for my setup.

Laravel Console Commands

Console commands implementation in Laravel is basically an implementation of a command design pattern. Every command has its own handle method which is fired whenever a command is dispatched.

The command pattern is a behavioral design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters. — Wikipedia

Database commands in Laravel can be found in Illuminate\Database\Console\Migrations namespace. We just need to override them with our own implementations.

Adding New Options

Create a folder called Migration inside app/Console . We will place all of our migration commands inside this folder. Create a file called MigrateCommand.php .

app/Console/Migration/MigrateCommand.php

This class extends Illuminate\Database\Console\Migrations\MigrateCommand which is basically the class that implements migrate command ( php artisan migrate ). Notice that in the constructor we are extending its signature by appending our options --all and --schema . Then we call the parent constructor with required parameter.

We now need to register it as Laravel’s default migrate command. For this, create a service provider called VentureMigrationServiceProvider inside app/Http/Providers directory and register it inside config/app.php .

Note that this service provider extends Laravel’s migration service provider Illuminate\Database\MigrationServiceProvider instead of the default Illuminate\Support\ServiceProvider .

app/Http/Providers/ VentureMigrationServiceProvider.php

registerMigrateCommand extends the singleton object available in alias command.migrate and returns our own MigrateCommand. command.migrate alias points to Illuminate\Database\Console\Migrations\MigrateCommand object. So overriding command.migrate will override Laravel’s default MigrateCommand as well.