maarheeze / uuid-laravel
laravel integration for a simple uuid value object
Requires
- php: ^8.4
- illuminate/contracts: ^13.0
- illuminate/database: ^13.0
- maarheeze/uuid: ^3.0
Requires (Dev)
- ext-pdo_sqlite: *
- maarheeze/phpcs: ^2.0
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^13
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Laravel integration for maarheeze/uuid. Provides an Eloquent cast and a trait for using uuid's as primary keys.
Installation
composer require maarheeze/uuid-laravel
Usage
Using UUID as primary key
Add the HasUuidAsId trait to an Eloquent model, a uuid is automatically generated on creation.
use Illuminate\Database\Eloquent\Model; use Maarheeze\Uuid\Laravel\Model\Concerns\HasUuidAsId; class Article extends Model { use HasUuidAsId; }
$article = Article::create(['title' => 'Hello world']); $article->getKey(); // returns a UuidInterface instance
Casting a UUID column
Use UuidCast directly on any model attribute to cast it to a UuidInterface.
use Illuminate\Database\Eloquent\Model; use Maarheeze\Uuid\Laravel\Model\Casts\UuidCast; class Article extends Model { protected $casts = [ 'related_id' => UuidCast::class, ]; }
The cast takes the target class as a cast argument, defaulting to Maarheeze\Uuid\Uuid.
Typed identifiers
A model can use its own UuidInterface implementation instead of the generic Uuid, so
that $article->getKey() returns an ArticleId and a foreign key column returns the id
type it points at. Two things are needed, and both are easy to get half-right — the
idClass() override drives the model's own key (the cast on id, the generated id and
the id validation), while every other uuid column needs its own cast argument.
use Illuminate\Database\Eloquent\Model; use Maarheeze\Uuid\IsUuid; use Maarheeze\Uuid\Laravel\Model\Casts\UuidCast; use Maarheeze\Uuid\Laravel\Model\Concerns\HasUuidAsId; use Maarheeze\Uuid\UuidException; use Maarheeze\Uuid\UuidInterface; final readonly class ArticleId implements UuidInterface { use IsUuid; } /** * @property ArticleId $id * @property AuthorId|null $author_id */ class Article extends Model { use HasUuidAsId; /** * @return array<string, string> */ protected function casts(): array { return [ 'author_id' => UuidCast::class . ':' . AuthorId::class, ]; } /** * @return class-string<ArticleId> */ protected function idClass(): string { return ArticleId::class; } }
Keep the @return class-string<...> docblock on the idClass() override — without it
static analysis falls back to plain string and loses the id type. An argument that does
not implement UuidInterface throws an UnexpectedValueException when the model boots.
getKey() is deliberately not final, so a model can narrow its return type:
public function getKey(): ArticleId { $key = parent::getKey(); if (!$key instanceof ArticleId) { throw new UuidException('Invalid uuid found'); } return $key; }
License
MIT