Anonymous Migrations in Laravel
Published on by Paul Redmond
The Laravel team released Laravel 8.37 with anonymous migration support, which solves a GitHub issue with migration class name collisions. The core of the problem is that if multiple migrations have the same class name, it'll cause issues when trying to recreate the database from scratch.
In Laravel 8.37, the framework can now work with anonymous class migration files. Here's an example from the pull request tests:
use Illuminate\Database\Migrations\Migration;use Illuminate\Database\Schema\Blueprint;use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('people', function (Blueprint $table) { $table->string('first_name')->nullable(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('people', function (Blueprint $table) { $table->dropColumn('first_name'); }); }};
The anonymous class feature is also backward-compatible with named migration classes to benefit from this feature in Laravel 8!
It is unclear if the framework will update the migration stubs to use anonymous classes by default at some point; however, Pull Request #5585 updates laravel/laravel
app starter to use anonymous classes for the users
, password_resets
, and failed_jobs
migrations.
If you'd like to start using anonymous migrations in your projects by default, you could also Customize Stubs in Laravel within your application:
// stubs/migration.create.stub use Illuminate\Database\Migrations\Migration;use Illuminate\Database\Schema\Blueprint;use Illuminate\Support\Facades\Schema; return new class extends Migration{ /** * Run the migrations. * * @return void */ public function up() { Schema::create('{{ table }}', function (Blueprint $table) { $table->id(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('{{ table }}'); }};
Take care to remember the trailing semicolon (;
) at the end of the class:
$example = new class { // ...};
With the migration.stub
, migration.create.stub
and migration.update.stub
updated you can test it out:
$ php artisan make:migration --create=examples \ create_examples_tableCreated Migration: 2021_04_13_182612_create_examples
Next, you need to update the composer.json
in your app to support at minimum Laravel 8.37:
{ "require": { "laravel/framework": "^8.37", },}
Finally, make sure you run composer update
to update the composer.lock
in VCS, so the migration command works with a Laravel framework version compatible with this new feature:
composer update
You can learn more about this feature by checking out the Pull Request #36906.