logo

A cleaner fix for the duplicate ULID problem

Let Eloquent handle the unique id

Aaron Saray
Aaron Saray
2026-05-07

In a previous tip, I walked through a duplicate public_id bug caused by Eloquent::replicate() carrying the ULID over to the clone.

The fix I landed on was a replicating hook that overwrites public_id on the new instance.

That works, but while digging in the framework source I noticed Eloquent\Model::replicate() already spreads ...$this->uniqueIds() into its list of excluded attributes.

So instead of using a replicating hook, we can just tell Eloquent that public_id is a unique id and shouldn't come along for the ride:

trait HasPublicId
{
    protected static function bootHasPublicId(): void
    {
        self::creating(function (self $model): void {
            if (empty($model->public_id)) {
                $model->public_id = (string) Str::ulid();
            }
        });
    }

    public function uniqueIds(): array
    {
        return ['public_id'];
    }
}

Now replicate() strips public_id from the new instance, the creating hook sees an empty value on save, and a fresh ULID gets generated.

One hook, no asymmetry to explain.

Here to help,

Aaron

P.S. Going framework-source-diving for a cleaner fix is exactly the kind of nerdy thing folks in our community happily do for sport. Come fall down a rabbit hole with us.

Toss a coin in the jar if you found this helpful.
Want a tip like this in your inbox every weekday? Sign up below 👇🏼
email
No spam. Only real-world advice.