News

Anonymous Migrations in Laravel

Published
Anonymous Migrations in Laravel image

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_table
Created 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.

Paul Redmond photo

Staff writer at Laravel News. Full stack web developer and author.

Filed in

Sponsored

laravelcloud logo
Laravel Cloud

Easily create and manage your servers and deploy your Laravel applications in seconds.

Visit Laravel Cloud

The latest

View all →
NativePHP v4: Build Native iOS and Android UI in Blade image

NativePHP v4: Build Native iOS and Android UI in Blade

Read article
Laravel Lock: Distributed Locks for Models and Routes image

Laravel Lock: Distributed Locks for Models and Routes

Read article
Laravel Image Responses: Serve Resized Images From Routes image

Laravel Image Responses: Serve Resized Images From Routes

Read article
Pause All Laravel Queues During a Deploy image

Pause All Laravel Queues During a Deploy

Read article
Laravel Terminal UI for the artisan dev Command image

Laravel Terminal UI for the artisan dev Command

Read article
Pause All Queues and a New artisan dev UI in Laravel 13.25 image

Pause All Queues and a New artisan dev UI in Laravel 13.25

Read article