Laravel 11: using PHP’s 8 Enumerations (Enums) for database migrations, seeding, etc.
While learning Laravel I’ve encountered a small problem because I couldn’t remember the enum values that I’ve used inside the tables. So I thought it would be great if I could use some sort of “centralized” source of truth regarding these enums, values that should be the same no matter where I’m using them.
So let’s try and put the PHP’s 8 Enumerations to work. For this we assume we need to have an entries table which is going to have an enum column named “entry_type” that would have ‘event’, ‘note’ or ‘task’ as potential values.
First of all let’s create the needed Enum. In order to create an Enum we can use the new artisan command `make:enum`:
php artisan make:enum
You can see more about the Enums created by Laravel’s Artisan on a great article written in Laravel Daily: https://laraveldaily.com/post/laravel-11-artisan-make-enum-command
We chose to create a backed Enum inside the Enums directory, named EntryType.
Now if we look inside the app directory, we will see that the directory Enums was created and the EntryType.php file was put inside it.
Let’s update it with the values we need:
<?php
namespace App\Enums;
enum EntryType: string
{
case Event = 'event';
case Note = 'note';
case Task = 'task';
}
Now, if we go inside a migration where we need to add the values for the Enum data type, we simply write something like…
<?php
use App\Enums\EntryType;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('entries', function (Blueprint $table) {
$table->id();
$table->enum('entry_type', array_column(EntryType::cases(), 'value'))->default(EntryType::Event->value);
...
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('entries');
}
};
As you can see, we also set a default value, by taking the value of the Enum class for the “Event”.
Now it will be easy to use the same work on the Factories and Seeder.
For example, in an `EntryFactory` we can make something on the lines of this:
<?php
namespace Database\Factories;
use App\Enums\EntryType;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Entry>
*/
class EntryFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'content' => $this->faker->sentence,
'entry_type' => $this->faker->randomElement(array_column(EntryType::cases(), 'value')),
];
}
}
Same goes for seeders.
And this way we reduced the work time for creating all the initial setups. Instead of having to work in three/four places when we make a change for the enum database type values, we now only have to change inside the PHP’s Enum class. Hope this helped.