Installation:
composer require labrodev/uuidable
Ensure your project meets the PHP 8.1+ requirement.
Add UUID Column:
Add a uuid column to your migration (or existing table) using:
$table->uuid('uuid')->unique()->nullable()->default(DB::raw('(uuid_generate_v4()))'));
(Note: The default clause is optional if the trait handles generation.)
Apply Trait: Use the trait in your Eloquent model:
use Labrodev\Uuidable\ModelHasUuid;
class User extends Model
{
use ModelHasUuid;
}
First Use Case: Create a model instance—it will auto-generate a UUID:
$user = User::create(['name' => 'John Doe']);
echo $user->uuid; // e.g., "123e4567-e89b-12d3-a456-426614174000"
ModelHasUuid and its methods (e.g., fetchUuidColumn()).php artisan test in the package directory to understand behavior (e.g., UUID uniqueness, fallback logic).Auto-Generation:
boot() to ensure UUIDs are generated on creating events.creating(Model $model) in your model to validate UUIDs before saving:
protected static function bootModelHasUuid()
{
static::creating(function ($model) {
if (empty($model->{$model->fetchUuidColumn()})) {
$model->{$model->fetchUuidColumn()} = Str::uuid();
}
});
}
Custom Column Names:
fetchUuidColumn() for non-standard column names (e.g., custom_id):
protected function fetchUuidColumn(): string
{
return 'custom_id';
}
UUID as Primary Key:
id with uuid as the primary key in migrations:
$table->uuid('uuid')->primary();
getKeyName() in your model:
public function getKeyName()
{
return 'uuid';
}
API Responses:
protected $appends = ['uuid'];
protected $casts = ['uuid' => 'string'];
public function getUuidAttribute($value)
{
return Str::of($value)->replace('{5}', '-')->replace('{9}', '-');
}
Str::uuid() in seeders to generate deterministic UUIDs:
$user = User::create(['name' => 'Admin', 'uuid' => Str::uuid()]);
$table->uuid('user_id')->foreign()->constrained('users');
$this->partialMock(User::class, function ($mock) {
$mock->shouldReceive('fetchUuidColumn')->andReturn('uuid');
});
UUID Generation Race Conditions:
default(DB::raw('uuid_generate_v4()')) in migrations, ensure the database supports it (PostgreSQL, MySQL 8+).Primary Key Conflicts:
uuid is the primary key, ensure it’s marked as unique in migrations to avoid duplicates.SQLSTATE[23000] errors during create() operations.Trait Method Overrides:
fetchUuidColumn() must return a string. Non-string values (e.g., null) will cause runtime errors.UUID Length in Databases:
CHAR(36) may truncate UUIDs if not explicitly cast. Use BINARY(16) for binary UUIDs or VARCHAR(36) for strings.$table->binary('uuid')->as('uuid')->unique();
Laravel Scout Integration:
where clauses. Use whereKey() instead:
User::whereKey($uuid)->get();
Missing UUIDs:
composer.json for Labrodev\Uuidable).creating event fires (add a dd() in the trait’s boot() method temporarily).Performance:
Custom UUID Strategies:
use Ramsey\Uuid\Uuid;
protected function generateUuid(): string
{
return Uuid::uuid5(Uuid::NAMESPACE_DNS, 'example.com')->toString();
}
UUID Validation:
rules():
public function rules()
{
return [
'uuid' => 'required|uuid',
];
}
UUID Display:
public function getShortUuidAttribute()
{
return Str::limit($this->uuid, 8);
}
Fallback for Non-UUID Databases:
protected function fetchUuidColumn(): string
{
return 'uuid';
}
protected static function bootModelHasUuid()
{
static::created(function ($model) {
if (empty($model->uuid)) {
$model->uuid = Str::uuid();
$model->save();
}
});
}
How can I help you explore Laravel packages today?