Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Uuid Laravel Package

ryangjchandler/laravel-uuid

A lightweight Laravel package that brings UUID support to Eloquent models. It provides a simple trait for generating UUID primary keys and resolving models by UUID, making it easy to use UUIDs in place of auto-incrementing IDs.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and publish

composer require ryangjchandler/laravel-uuid
php artisan vendor:publish --tag="laravel-uuid-config"   # if you need to customize the column/version

The package is tiny — there is no service provider surface to learn beyond the config file and one trait. Read the trait source first (usually src/HasUuids.php); it is short enough to audit in a couple of minutes and tells you exactly which model event the UUID is assigned on.

Wire it into a model

use RyanChandler\LaravelUuid\HasUuids;

class Post extends Model
{
    use HasUuids;
}

Migration — match the column type the package writes to:

Schema::create('posts', function (Blueprint $table) {
    $table->id();                 // keep the auto-increment PK if using a secondary column
    $table->uuid('uuid')->unique();
    // or, if the UUID *is* the key:
    // $table->uuid('id')->primary();
    $table->timestamps();
});

First use case: you have an internal id you don't want to leak in URLs, API payloads, or exports. Add the trait, add a uuid column, point route model binding at it, and you're done:

public function getRouteKeyName(): string
{
    return 'uuid';
}

That is the 80% case — a public-facing opaque identifier alongside a fast integer primary key.

Implementation Patterns

Secondary column (recommended default). Keep the integer PK for joins and index density, and use the UUID purely as an external identifier. Hide the integer in API resources:

class PostResource extends JsonResource
{
    public function toArray($request): array
    {
        return [
            'id'    => $this->uuid,
            'title' => $this->title,
        ];
    }
}

UUID as the primary key. Only do this if you accept the trade-offs (larger indexes, no natural ordering). You typically need to tell Eloquent about it:

protected $keyType = 'string';
public $incrementing = false;

Check whether the trait already sets these — some versions do, some expect you to. Verify with php artisan tinker after creating a record.

Route model binding by UUID. Set getRouteKeyName() to the UUID column and make sure the column is indexed/unique. Controllers and Route::resource calls then need no changes:

Route::get('/posts/{post}', [PostController::class, 'show']);
// resolves via uuid, 404s correctly on unknown values

Combining with relationships. Foreign keys must use the same column type as the referenced key. If you reference a UUID primary key:

$table->foreignUuid('post_id')->constrained();

If you use a secondary UUID column, reference that column explicitly: ->constrained('posts', 'uuid').

Factories and seeders. Factories generally don't need to set the UUID — the trait fills it on creating. But seeding with Model::insert() or upsert() bypasses model events entirely, so generate UUIDs manually in bulk paths:

Post::insert($rows->map(fn ($r) => [...$r, 'uuid' => (string) Str::uuid()])->all());

Testing. Assert the shape rather than exact values:

$this->assertTrue(Str::isUuid($post->uuid));
$this->assertSame($post->uuid, Post::find($post->id)->uuid); // persisted, not just in-memory

Gotchas and Tips

  • Laravel already ships this. Since Laravel 9, Illuminate\Database\Eloquent\Concerns\HasUuids and HasUlids exist natively. If you're on a modern Laravel, prefer the framework trait unless this package gives you a specific feature (ordered UUIDs, a separate column, a particular UUID version). Adopting a third-party trait that shadows a framework concern creates confusion for future maintainers.
  • Bulk operations skip the trait. insert, upsert, updateOrCreate on the query builder, and raw SQL will not trigger the creating event. Always backfill UUIDs in those code paths, or you get NULL violations / duplicate empty strings.
  • Column type mismatches. $table->uuid() is char(36) on MySQL but a native uuid type on Postgres. Mixing a char(36) foreign key with a native uuid column will fail on Postgres — keep both sides consistent.
  • Config caching. If you change the column name or UUID version in config, run php artisan config:clear (or re-cache in deploy). A stale cached config is the usual cause of "it's writing to the wrong column."
  • Don't set the UUID yourself and expect it to stick — depending on version, the trait may overwrite an existing value on creating. If you need deterministic IDs (fixtures, imports), check the trait's guard clause or set the attribute after create() + save().
  • Route binding 404s. If {post} returns 404 for a valid UUID, your route key name and the actual column disagree, or you never added the unique() index and an older row is NULL.
  • Index locality. Random UUIDv4 primary keys fragment B-tree indexes on write-heavy tables. If insert throughput matters, use ordered UUIDs (ULID / UUIDv7) — check whether this package supports an ordered variant before rolling your own.
  • Extension point. The trait's generation method is the natural override: subclass the trait or override the booted method in your model to swap in a different UUID source without touching the package.
  • Debugging checklist: confirm the trait is actually used on the model, confirm the model fires creating (log it), confirm the column exists in the DB, then confirm the value persists after refresh(). That ordering finds the problem in under a minute.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names