Laravel change migration order
-
Roll back all the migrations (or start with a fresh database);
-
Change the dates that form the first part of the migration filenames so they're in the order you want (eg. for
2014_06_24_134109_update_database.php
, the date & time is 2014-06-24, 13:41:09); -
Run the migrations again.
With respect to your comment about foreign keys... I'm not sure that the problem is with Laravel. More likely, it's just MySQL.
I avoid foreign keys because once you get a moderately complicated set of relations, you start to run into problems with database consistency like you're seeing - it's hard for the server to figure out what order to create the tables & relationships in, and it starts to cause difficulties with things like dump files (for backups).
You have to create a custom command that executes
php artisan migrate:refresh --path=/database/migrations/name_migration.php
repeately with the migrations's name in the order you want.
Like this:
- Create Command class with:
php artisan make:command NameClass
- Go to
app/Console/Commands/
and find the class fileNameClass.php
- In the NameClass.php you have two attributes
$signature
(the name of the command) and$description
(Information about what your command does). - Set the name and the description of your command.
Ex: protected $signature='namecommand'; protected $descripton = 'This method migrate tables in order'
- Inside the NameClass.php you have a method called
handle()
, here you have to declare the code you want to be executed when you write the command. - Register your command. Go to
app/Console/Kernel.php and
add your class to the list of Command Classes.protected $commands = [ Commands\NameClass::class, ];
- Write the command in the terminal.
php artisan namecommand
Example:
php artisan make:command MigrateInOrder
app/Console/Commands/MigrateInOrder.php
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class MigrateInOrder extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'migrate_in_order';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Execute the migrations in the order specified in the file app/Console/Comands/MigrateInOrder.php \n Drop all the table in db before execute the command.';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
/** Specify the names of the migrations files in the order you want to
* loaded
* $migrations =[
* 'xxxx_xx_xx_000000_create_nameTable_table.php',
* ];
*/
$migrations = [
'2020_04_18_005024_create_users_types.php',
'2014_10_12_000000_create_users_table.php',
'2014_10_12_100000_create_password_resets_table.php',
'2019_08_19_000000_create_failed_jobs_table.php'
];
foreach($migrations as $migration)
{
$basePath = 'database/migrations/';
$migrationName = trim($migration);
$path = $basePath.$migrationName;
$this->call('migrate:refresh', [
'--path' => $path ,
]);
}
}
}
- Go to app/Console/Kernel.php and register your command
protected $commands = [
Commands\MigrateInOrder::class,
];
- Excute the command
php artisan migrate_in_order
The best and easiest thing would be to just rename the migration yyyy_mm_dd_hhmmss_migration_name
. If your migration follows this sequence, Laravel will ensure to run the migration is sorted form of date,