简体   繁体   中英

Laravel migration package publishing order

I'm building a Laravel Package. I need to publish my custom migrations. One migration need another one to be run because it has a foreign key constraint.

In my service provider I'm doing this:

public function boot(Filesystem $filesystem)
    {
        $this->loadMigrationsFrom(dirname(__DIR__).'/migrations');
        $this->publishMigrations($filesystem);    
    }


private function publishMigrations(Filesystem $filesystem)
    {
        if (! class_exists('CreateReferencedTable')) {
            $this->publishes([
                __DIR__ . '/../database/migrations/create_referenced_table.php.stub' => $this->getMigrationFileName($filesystem, 'referenced')              
            ], 'migrations');
        }
        if (! class_exists('CreateExampleTable')) {
            $this->publishes([
                __DIR__ . '/../database/migrations/create_example_table.php.stub' => $this->getMigrationFileName($filesystem, 'example')           
            ], 'migrations');
        }
    }

    protected function getMigrationFileName(Filesystem $filesystem, string $table_name): string
    {
        $timestamp = date('Y_m_d_His');
        return Collection::make($this->app->databasePath().DIRECTORY_SEPARATOR.'migrations'.DIRECTORY_SEPARATOR)
            ->flatMap(function ($path, $table_name) use ($filesystem) {
                return $filesystem->glob($path.'*_create_'.$table_name.'_table.php');
            })->push($this->app->databasePath()."/migrations/{$timestamp}_create_{$table_name}_table.php")
            ->first();
    }

And then I run

php artisan vendor:publish --provider="FedericoArona\MyPackage\Providers\MyServiceProvider" --tag="migrations"

The problem is that the tables are being created with the exact same timestamp so they will be ordered by their name. This means that "Example" migration will be created before "Referenced" migration.

Obviously this means that when I run my migrations, they will fail because "Example" migration need to be run after "Referenced".

How can I solve? Thanks.

The only approach I've made work is a hack: adjust the timestamps. I put the number of migrations into a property in the provider

$this->migrationCount

and then decrement the timestamp (so if the tick counter increments in the middle of execution it still is different):

    private function migratePath(string $file): string
    {
        $timeKludge = date('Y_m_d_His', time() - --$this->migrationCount);
        return database_path(
            'migrations/' . $timeKludge . "_$file.php"
        );
    }

It's not pretty but it works.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM