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.
the error message is just like this, there is no more explanation.
I'm using the command php artisan db:wipe
before using this command (I didn't feel that it's safe to include this command in handle() method and I think It's better to wipe database data in a separate clear command).
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.
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]);
}
}
}