Laravel change migration order

  1. Roll back all the migrations (or start with a fresh database);

  2. 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);

  3. 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:

  1. Create Command class with: php artisan make:command NameClass
  2. Go to app/Console/Commands/ and find the class file NameClass.php
  3. In the NameClass.php you have two attributes $signature (the name of the command) and $description (Information about what your command does).
  4. Set the name and the description of your command.Ex: protected $signature='namecommand'; protected $descripton = 'This method migrate tables in order'
  5. 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.
  6. Register your command. Go to app/Console/Kernel.php and add your class to the list of Command Classes. protected $commands = [ Commands\NameClass::class, ];
  7. Write the command in the terminal. php artisan namecommand

Example:

  1. php artisan make:command MigrateInOrder

  2. 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 ,            
           ]);
        }
    }
} 
  1. Go to app/Console/Kernel.php and register your command
    protected $commands = [
        Commands\MigrateInOrder::class,
    ];
  1. Excute the command
   php artisan migrate_in_order

Taking inspiration from PhpMyAdmin, I put all foreign keys definitions in a specific far future file, eg : 2999_12_31_235959_foreign_key.php

<?php

use App\Models\Post;
use App\Models\Tag;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class ForeignKeys extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        // Post_tag
        Schema::table(Post::NOM, function (Blueprint $table) {
            $table->foreign('id_post')
                ->references('id_post')
                ->on(Post::NOM);

            $table->foreign('id_tag')
                ->references('id_tag')
                ->on(Tag::NOM);
        });
    }
}

The only con I see is not having foreign keys definition in migration.

For the pros :

  • Keeping database relations
  • Do not care of table creation order