Search code examples
phpenumsphp-8.1

Laravel Enum casting error Call to undefined method App\\Enums\\UserType::from()


When I try to cast a attribute from my model to one of my enums, it throws an erro:

Call to undefined method App\Enums\UserType::from()

I can not find anything about the required find() method.

I followed the instructions here.

My Enum UserType:

namespace App\Enums;

enum UserType
{
    case CUSTOMER;
    case PARTNER;
    case ADMIN;
}

And my User-model:

namespace App\Models;

use App\Enums\UserType;
use FaarenTech\LaravelCustomUuids\Interfaces\HasCustomUuidInterface;
use FaarenTech\LaravelCustomUuids\Models\UuidModel;
use Illuminate\Auth\MustVerifyEmail;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableInterface;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableInterface;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordInterface;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use Illuminate\Auth\Authenticatable;
use Illuminate\Foundation\Auth\Access\Authorizable;
use Illuminate\Auth\Passwords\CanResetPassword;

class User extends UuidModel implements
    AuthorizableInterface,
    AuthenticatableInterface,
    CanResetPasswordInterface,
    HasCustomUuidInterface
{
    use
        HasApiTokens,
        HasFactory,
        Notifiable,
        Authenticatable,
        Authorizable,
        CanResetPassword,
        MustVerifyEmail,
        SoftDeletes;

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
        'type' => UserType::class
    ];
}

Solution

  • You need to map each enum to a scalar value (int, float, string, bool), this way Laravel can convert from the (database stored) value -> enum.

    e.g.

    enum UserType: string
    {
        case CUSTOMER = 'CUSTOMER';
        case PARTNER = 'PARTNER';
        case ADMIN = 'ADMIN';
    }
    

    See Backed Enums in PHP:

    Backed enums implement an internal BackedEnum interface, which exposes two additional methods:

    from(int|string): self will take a scalar and return the corresponding Enum Case. If one is not found, it will throw a ValueError. This is mainly useful in cases where the input scalar is trusted and a missing enum value should be considered an application-stopping error.