laravelmigrationlaravel-migrations

How to set migration execution order in Laravel using a command class


I'm trying to change the execution order of Laravel migrations because of foreign key constraints and I found some solutions like:

1- it can be done by renaming migration files to get it in the requested order.

2- You don't really need to change the migration order, just create the child table without a foreign key column then create the parent table then add the foreign key column to the child (which looks like a good approach if your database contains real data but now I'm in development phase and I think this will add too much unnecessary migrations to the project).

but I didn't do it because it feels like there should be a better approach, and then I knew it can be done be defining a command class, so I did it like this:

class OrderMigrations extends Command
{
    protected $signature = 'migrate:staged';

    protected $description = 'Executes migrations in a specific order';

    public function handle()
    {
        // this command is working fine.
        $this->call('list');

        // these commands are not working
        $this->call('migrate --path=database/migrations/2024_06_24_102218_create_roles_table.php');
        $this->call('migrate --path=database/migrations/0001_01_01_000000_create_users_table.php');
        $this->call('migrate --path=database/migrations/0001_01_01_000001_create_cache_table.php');
        $this->call('migrate --path=database/migrations/0001_01_01_000002_create_jobs_table.php');
        $this->call('migrate --path=database/migrations/2024_06_04_171913_create_products_table.php');
    }
}

I tested for the list command as shown in the code and it worked fine, but for some reason it isn't working for creating migrations and I'm getting this error:

 ERROR  Command "migrate --path=database/migrations/0001_01_01_000000_create_users_table.

How can I fix it? and does renaming migration files approach have benefits over this approach? I didn't really find any well detailed explanation about the difference between them.


Solution

  • I just replaced $this->call() with Artisan::call() and it worked, it's better to use an array with migration names though.

    class OrderMigrations extends Command
    {
        protected $signature = 'migrate:staged';
    
        protected $description = 'Executes migrations in a specific order';
    
        public function handle()
        {
            $migrations = [
                '2024_06_24_102218_create_roles_table.php',
                '0001_01_01_000000_create_users_table.php',
                '0001_01_01_000001_create_cache_table.php',
                '0001_01_01_000002_create_jobs_table.php',
                '2024_06_04_171913_create_products_table.php'
            ];
    
            $basePath = 'database/migrations/';
    
            foreach ($migrations as $migration) {
                $path = $basePath.trim($migration);
                Artisan::call('migrate', ['--path' => $path]);
            }
        }
    }