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

Eloquent Uuid Laravel Package

marquine/eloquent-uuid

marquine/eloquent-uuid adds UUID primary key support to Laravel Eloquent models, replacing auto-incrementing integer IDs with globally unique identifiers through a simple trait. Models keep their usual relationships and query behavior while gaining non-sequential, harder-to-guess keys with minimal c...

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal steps

  1. composer require marquine/eloquent-uuid
  2. Inspect what you actually installed before relying on it:
    • composer.json in vendor/marquine/eloquent-uuid — check the illuminate/* and php constraints against your app. With 7 stars and 0 dependents, this package was likely written for Laravel 5.x/6.x; confirm it installs at all on Laravel 10/11/12.
    • src/ — identify the trait's exact FQCN (typically something like Marquine\EloquentUuid\HasUuid) and read its boot…() method to see which model event generates the UUID.
    • README.md — the canonical usage snippet.
  3. Add the trait to a model:
use Marquine\EloquentUuid\HasUuid; // verify FQCN in vendor/marquine/eloquent-uuid/src

class Order extends Model
{
    use HasUuid;
}
  1. Write the migration with a UUID primary key (not bigIncrements):
Schema::create('orders', function (Blueprint $table) {
    $table->uuid('id')->primary();
    $table->uuid('user_id')->index();
    $table->timestamps();
});

Where to look first: the trait source, not the README. You need to know whether it hooks creating, sets $keyType/$incrementing for you, and whether it can generate a custom version/namespace UUID.

First use case: a greenfield model where you want non-guessable, client-generatable IDs — e.g. an Order or Invoice whose ID appears in URLs, outbound emails, or is created offline before sync.

Reality check before you start: Laravel 9+ ships Illuminate\Database\Eloquent\Concerns\HasUuids (and HasUlids). For any modern app this package is almost certainly redundant — the correct "getting started" step is often to use the framework trait instead and skip the dependency entirely.

Implementation Patterns

Consistent trait application. Apply it to every model that owns a UUID PK, and be explicit in the model rather than relying on a base class you might forget:

abstract class UuidModel extends Model
{
    use HasUuid;
}

But prefer per-model traits — a base class that silently flips $incrementing is a common source of confusion for the next developer.

Migrations and foreign keys. Every referencing column must be uuid, and the parent must be created first:

$table->foreignUuid('order_id')->constrained()->cascadeOnDelete();
// or pre-Laravel 7 syntax: $table->uuid('order_id'); $table->foreign('order_id')->references('id')->on('orders');

Mixing foreignId (bigint) with a UUID PK is the single most common integration failure.

Route model binding just works. Because the key is a string, Route::get('/orders/{order}', ...) resolves via getRouteKey() with no changes. You get 404s automatically for malformed/unknown IDs — no where('id', '[0-9]+') constraint needed, which is a nice win.

Factories. Don't hard-code IDs; let the trait generate them. If you need deterministic IDs in tests, override explicitly:

Order::factory()->create(['id' => Str::uuid()]);

Relationships. hasMany/belongsTo need no special handling, but set protected $keyType = 'string'; on any related model if you also query it by key outside Eloquent's generated SQL.

Bulk operations are the trap. Model events drive UUID generation, so Order::insert([...]), DB::table('orders')->insert(), upsert(), and insertGetId() will produce NULL or failing primary keys. For imports, build models and save() them, or generate IDs yourself with Str::uuid() in the array.

API/JSON layer. UUID PKs serialize as strings — fine for JSON — but if you have clients expecting integers, this is a breaking contract change. Treat the migration as a v2 API concern, not a refactor.

Drop-in alternative pattern. If you're on Laravel 9+, the equivalent native implementation is:

use Illuminate\Database\Eloquent\Concerns\HasUuids;

class Order extends Model { use HasUuids; }

Same migration shape, no third-party dependency, framework-maintained. Migration from this package is usually a one-line trait swap.

Gotchas and Tips

  • $incrementing and $keyType. The trait may or may not set these. Verify with $model->getIncrementing() and $model->getKeyType() in php artisan tinker. If getIncrementing() is true, inserts will try to treat your UUID as an auto-increment integer and fail confusingly.
  • Silent event bypass. Model::insert() skips creating. If you see SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'id' cannot be null, that's the cause — not a trait misconfiguration.
  • Ordering and pagination. UUIDv4 is random; ORDER BY id is meaningless and index locality is poor on insert-heavy tables. Use created_at for ordering, or switch to ULIDs/UUIDv7 if sortable keys matter.
  • Storage size. char(36) PKs bloat indexes. For high-volume tables, consider binary(16) with a cast — but that is well beyond what this package offers, so don't expect help there.
  • Uniqueness collisions are hypothetical, not real. Don't write retry logic; do ensure the column is unique/primary so the DB enforces it.
  • Trait boot method naming. Eloquent boots traits via boot{TraitName}. If you alias or wrap the trait in your own class, the boot hook may not fire — the symptom is NULL IDs with no error until the DB rejects the insert. Debug by dumping $model->getKey() in a creating listener.
  • Conflict with other UUID packages. ramsey/uuid, wildbit/laravel-uuid, spatie/laravel-uuid, and Laravel's native traits can all collide on $keyType, casts, or boot hooks. Use exactly one.
  • Extension point. If the trait exposes a generateUuid()-style method (check the source), override it in your model to control version/namespace or to use ULIDs. That's the cleanest way to adapt the package without forking.
  • Maintenance risk is the headline gotcha. 7 stars, 0 dependents, and a very low score mean no ecosystem pressure to keep it compatible with current Laravel. Before adopting: check the last commit date and whether composer require resolves on your PHP/Laravel pair. On anything Laravel 9+, prefer the built-in HasUuids; on older versions, ramsey/uuid inside a creating hook is a five-line, dependency-light alternative you fully control.
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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource