how to use enum attribute casting in laravel 9

In this section we will see how to use enum attribute casting in laravel 9. Php 8.1 support enum feature with the help of enum we can write readable code. Before we start i suggest you read previous blog.

Laravel 9 Store Enum Value with Validation Example


Run below command to create laravel project.

composer create-project laravel/laravel project-name

Now, you have to connect the laravel app to the database, hence open the .env configuration file and add the database credentials as suggested below.

.env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=database_name
DB_USERNAME=database_user_name
DB_PASSWORD=database_password


Create Model Migration and Controller

php artisan make:model Blog -mcr


there two way we can use enum casting in migration use enum or use string.

1. Enum status and give enum value 'published','draft','archived'.

create_blogs_table.php

public function up()
{
    Schema::create('blogs', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->text('content');
        $table->enum('status',['published','draft','archived']);
        $table->timestamps();
    });
}


2. Enum status and give string value 'status' and default value draft.

create_blogs_table.php

public function up()
{
    Schema::create('blogs', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->text('content');
        $table->string('status')->default('draft');
        $table->timestamps();
    });
}


Create Enums Class in Laravel 9

1. First you need to create Enums Folder and inside add php file PostStatus.php.

2. Add case, Published, Draft, Archived

3. give three of them value like published, draft, archived.

laravel enum attribute casting folder structure

laravel enum attribute casting folder structure

app/Enums/PostStatus.php

<?php

namespace App\Enums;

enum PostStatus: string
{
    case Published = 'published';
    case Draft = 'draft';
    case Archived = 'archived';
}


Add Enum Casting in Blog.php model

app/Models/Blog.php

<?php

namespace App\Models;

use App\Enums\PostStatus;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Blog extends Model
{
    use HasFactory;

    protected $fillable = [
        'title',
        'content',
        'status'
    ];

    protected $casts = [
    'status' => PostStatus::class
    ];
}


Use Enum Class in Laravel Seeder

Create blog seeder in laravel 9

php artisan make:seeder BlogSeeder

Create 'published','draft','archived' in Sedder using Enum class.

seeders/BlogSeeder.php

<?php

namespace Database\Seeders;

use App\Models\Blog;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class BlogSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $data = [
            [
                'title' => 'PHP',
                'content' => 'lorem',
                'status' => \App\Enums\PostStatus::Published,
                'created_at' => now(),
            ],
            [
                'title' => 'Python',
                'content' => 'lorem',
                'status' => \App\Enums\PostStatus::Draft,
                'created_at' => now(),
            ],
            [
                'title' => 'Javascript',
                'content' => 'lorem',
                'status' => \App\Enums\PostStatus::Archived,
                'created_at' => now(),
            ],
            [
                'title' => 'Ruby',
                'content' => 'lorem',
                'status' => \App\Enums\PostStatus::Published,
                'created_at' => now(),
            ],
        ];
        Blog::insert($data);
    }
}

run fresh migrate to seeder

php artisan migrate:fresh --seed


Laravel 9 Show Data Using Enum Class

show publish data using enum class.

public function index()
{
    $blogs = Blog::where('status', \App\Enums\PostStatus::Published)->get();
    
    return view('blogs.index', compact('blogs'));
}

show draft data using enum class.

public function index()
{
    $blogs = Blog::where('status', \App\Enums\Draft::Published)->get();
    
    return view('blogs.index', compact('blogs'));
}

show archived data using enum class.

public function index()
{
    $blogs = Blog::where('status', \App\Enums\Draft::Archived)->get();
    
    return view('blogs.index', compact('blogs'));
}


Store Publish Data in laravel 9 using Enum

You can use \App\Enums\PostStatus::Published to create publish data or use Draft to create or update data.

$blog = Blog::create([
    'title' => 'Enums Casting in Laravel 9!',
    'content' => 'lorem',
    'status' => \App\Enums\PostStatus::Published,
]);


Validate Enum in Laravel 9

We can use validate enum using Enum Rules and Enum class.

app/Http/Controllers/BlogController.php

<?php

namespace App\Http\Controllers;

use App\Models\Blog;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\Enum;

class BlogController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $blogs = Blog::where('status', \App\Enums\PostStatus::Published)->get();
        
        return view('blogs.index', compact('blogs'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return view('blogs.create');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $request->validate([
            'title' => ['required', 'string', 'max:255'],
            'content' => ['required'],
            'status' => ['required', Rule::in(\App\Enums\PostStatus::class)],
            'status' => ['required', new Enum (\App\Enums\PostStatus::class)],

        ]);


        $blog = Blog::create([
            'title' => $request->title,
            'content' => $request->content,
            'status' => $request->status,
        ]);


        return redirect()->route('blogs.index');
    }

}