How To Work With Enumerations in Laravel Framework 9
Laravel 9 was released on February 8th, 2022 and it came with some nice new features that we want to highlight.
In this article, we’ll discuss how to work with enumerations in Laravel Framework 9+
Enums were our favorite new feature added in PHP 8.1 so we’re so glad to see them being included already in Laravel.
That being said you must be using PHP 8.1 for the new Enum features to work.
Enum Eloquent Attribute Casting
A new feature was added to Eloquent’s attribute casting to support casting values from a database value to an enum.
For this example we’ll create an article model with four potential published states. We’ll be using an enum to store the values.
Out of the box, Laravel doesn’t have an “Enums” folder but it seems to make sense to create one inside of our “app” directory. Then we’re not mixing models that interface with the database with enums that don’t.
namespace App\Enums;
enum PublishedState: string {
case NotPublished = '1';
case Scheduled = '2';
case Published = '3';
case Deleted = '4';
}
Now let’s create our model.
$ php artisan make:model -m Article
Model created successfully.
Created Migration: 2022_02_19_180106_create_articles_table
Inside our migration we’ll create a column named “state_id” with a default value of PublishedState::NotPublished
.
public function up()
{
Schema::create('articles', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('title');
$table->text('article_body');
$table->integer('state_id')->nullable(false);
});
}
Now inside our model we’ll specify that we can fill our state_id and in our casts
attribute we’ll define how the state_id
should be the PublishedState
enum (it says class but it’s not).
<?php
namespace App\Models;
use App\Enums\PublishedState;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
use HasFactory;
protected $fillable = [
'state_id',
'title',
'article_body'
];
protected $casts = [
'state_id' => PublishedState::class,
];
}
Now when we create a new Article
we can specify
$article = \App\Models\Article::create([
'title' => 'Enums in Laravel 9!',
'article_body' => 'Something',
'state_id' => \App\Enums\PublishedState::NotPublished,
]);
When we var_dump the value of state_id
out we can see that it’s the enum and not the value of the enum.
var_dump($article->state_id);
enum(App\Enums\PublishedState::NotPublished)
Now the great part about enums is that we’re not supposed to be able to set one to an invalid value. Look what happens when we try.
$article->state_id = 12;
12 is not a valid backing value for enum "App\Enums\PublishedState"
So glad these have been added.
Implicit Route Bindings With Enums
The next piece of enum logic we want to use is the fact that we can now use Enums in our routing table to only allow specific values.
Let’s look at an example where we want to filter our list of articles based on their current state. We can define a route like so.
Route::get('/articles/{state}', function (int $state) {
return $state;
});
Again the downside to this is that we can pass any value we want into the route and have it work. For example, we can visit “/articles/77” and it will route. We’ll filter out our results but they’ll be empty because it’s an invalid state_id.
If we change the route definition to look for our enum it will look like the following.
Route::get('/articles/{state}', function (\App\Enums\PublishedState $state) {
return $state->value;
});
And our “/articles/1” will still work but when we attempt to access “/articles/77” we’ll get a 404 error. We’re still struggling with if this is how we want our application to behave but it’s a good start.
What You Need to Know
- Laravel 9 added support for enums
- Must be using PHP 8.1 or higher
- Can cast to an enum
- Can use for routes
Scott Keck-Warren
Scott is the Director of Technology at WeCare Connect where he strives to provide solutions for his customers needs. He's the father of two and can be found most weekends working on projects around the house with his loving partner.
Top Posts
- Working With Soft Deletes in Laravel (By Example)
- Fixing CMake was unable to find a build program corresponding to "Unix Makefiles"
- Upgrading to Laravel 8.x
- Get The Count of the Number of Users in an AD Group
- Multiple Vagrant VMs in One Vagrantfile
- Fixing the "this is larger than GitHub's recommended maximum file size of 50.00 MB" error
- Changing the Directory Vagrant Stores the VMs In
- Accepting Android SDK Licenses From The OSX Command Line
- Fixing the 'Target class [config] does not exist' Error
- Using Rectangle to Manage MacOS Windows