spatie/laravel-enum
Laravel integration for spatie/enum: use Enum base class in Laravel, cast model attributes to enums (including nullable and arrays), and get Laravel-friendly behavior via custom casts and Castable support for Eloquent.
Installation:
composer require spatie/laravel-enum
Publish the config (optional):
php artisan vendor:publish --provider="Spatie\LaravelEnum\EnumServiceProvider"
Define an Enum:
use Spatie\Enum\Enum;
class UserRole extends Enum
{
public const ADMIN = 'admin';
public const EDITOR = 'editor';
public const VIEWER = 'viewer';
}
First Use Case:
use Spatie\Enum\WithEnums;
class StoreUserRoleRequest extends FormRequest
{
use WithEnums;
public function rules()
{
return [
'role' => ['required', 'enum:UserRole'],
];
}
}
use Spatie\LaravelEnum\HasEnums;
class User extends Model
{
use HasEnums;
protected $enumCasts = [
'role' => UserRole::class,
];
}
app/Enums/ (create this directory).protected $enumCasts in Eloquent models.enum: rule in Form Requests or Controllers.toEnum() in API resources.Database Storage & Retrieval:
// Store
$user = User::create(['role' => UserRole::ADMIN]);
// Retrieve
$role = $user->role; // Returns UserRole object
$role->value; // 'admin'
Validation & Sanitization:
// Form Request
$request->validate(['role' => ['required', 'enum:UserRole']]);
// Controller
$role = UserRole::from($request->role); // Throws exception if invalid
API Responses:
// Resource
public function toArray($request)
{
return [
'role' => $this->role->value, // or $this->role->toString()
];
}
Dynamic Enum Filtering:
// Query Builder
User::whereEnum('role', UserRole::ADMIN)->get();
Enum in Collections:
$users = User::all();
$admins = $users->whereEnum('role', UserRole::ADMIN);
Migration Workflow:
$table->string('role')->comment('UserRole enum');
Seeding:
User::create(['role' => UserRole::VIEWER]);
Testing:
$this->assertEquals(UserRole::EDITOR, $user->role);
$this->assertTrue(UserRole::isValid('admin'));
Spatie\LaravelEnum\Nova\EnumField for custom fields.toSearchableArray to include enum values.toArray to return enum values as strings or objects.public function canEdit(User $user)
{
return $user->role->is(UserRole::ADMIN);
}
Case Sensitivity:
strtolower or strtoupper if needed:
public const ADMIN = 'admin';
// vs
public const ADMIN = 'Admin';
Database Collation:
utf8mb4_unicode_ci).Mass Assignment:
$fillable:
protected $fillable = ['role'];
Serialization:
toJson() or fromJson():
$role = UserRole::fromJson('"admin"');
Caching:
php artisan config:clear
Invalid Enum Values:
Spatie\Enum\Exceptions\InvalidEnumValueException in try-catch blocks:
try {
$role = UserRole::from('invalid');
} catch (InvalidEnumValueException $e) {
// Handle error
}
Database Mismatches:
'strict' => true, // Throws exception on invalid DB values
Enum Not Found:
composer dump-autoload).Reusable Enums:
app/Shared/Enums) for multi-project use.Enum Methods:
class UserRole extends Enum
{
public function canEdit(): bool
{
return $this->is(self::ADMIN) || $this->is(self::EDITOR);
}
}
Localization:
class UserRole extends Enum
{
public function label(): string
{
return __("roles.{$this->value}");
}
}
Performance:
public function boot()
{
Enum::macro('allValues', function () {
return array_values(array_filter(get_class_vars(get_called_class()), 'is_string', ARRAY_FILTER_USE_KEY));
});
}
Testing:
$this->partialMock(UserRole::class, function ($mock) {
$mock->shouldReceive('is')->andReturnTrue();
});
Config Customization:
config/enum.php:
'cast_as_string' => false, // Return enum objects instead of strings
'throw_on_invalid' => true, // Throw exception on invalid values
Dynamic Enums:
Spatie\Enum\DynamicEnum for runtime-defined enums (advanced use case).How can I help you explore Laravel packages today?