Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Zini's avatar
Level 1

How to use database engine's UUIDs with Eloquent?

Hello,

I want to use UUIDs generated by PostgreSQL to avoid relying on a Laravel package for the functionality that is provided directly by the database.

The UUIDs work and can be retrieved afterwards, but Eloquent has a problem doing so directly after saving objects.

The migration defines the PostgreSQL UUID generation:

    Schema::create('users', function (Blueprint $table) {
        $table->uuid('uuid')->primary()->default(DB::raw('uuid_generate_v4()'));
        $table->string('name')->unique();
    });

But when I create a user, I cannot directly access its uuid:

$user = new User;
$user->name = 'test';
$user->save();
$user->uuid     // here it is null, this property doesn't even exist

How can I get my uuid generated by PostgreSQL directly after save()? How does Eloquent proceed in the case of classic ids?

0 likes
9 replies
gregrobson's avatar

In your model is the incrementing property set to false?

class MyModel extends Model
{
    protected $primaryKey = 'uuid';

    public $incrementing = false;
}

Primary keys are assumed to be integers by default (and incrementing) so it's probably trying to cast the uuid string to an integer and returning null.

If that doesn't work, then you might need to explicitly cast the uuid property as well.

    $casts = [
        'uuid' => 'string',
    ]
Zini's avatar
Level 1

Yes, my model already declares $primaryKey and $incrementing, adding the $casts array doesn't change anything.

The action of creating a new User works, a user is indeed created with its uuid, the problem is that $user->uuidcannot be directly accessed after saving this new user. It can only be accessed after an Eloquent get User::last()->uuid.

gregrobson's avatar

Okay, if it's saving then what is the output if you do dd($user); after you save. Perhaps looking at the instance will give something away?

Zini's avatar
Zini
OP
Best Answer
Level 1

I think I got what was going wrong:

Eloquent was designed with only incremental ids in mind. To replace a model's incremental id by a uuid, you will find a lot of people on the internet telling you to disable incrementing on your model. This is wrong, uuids are not incremental, but for Eloquent "incremental" doesn't actually mean incremental, it means "being generated by a database trigger" (source) and our uuids should be database-generated.

To use uuids auto-generated on the database level, define the model as follows:

class MyModel extends Model
{
    // rename the id column, not mandatory
    protected $primaryKey = 'uuid';

    // tell Eloquent that uuid is a string, not an integer
    protected $keyType = 'string';
}

(in my first tests it seems to work fine)

Thank you gregrobson for pointing out the $casts property!

Edit: And thanks to martinbean for improving it with $keyType!

1 like
gregrobson's avatar

Glad we got it sorted in the end. Always nice to see other Postgres users on here :-)

1 like
martinbean's avatar

@Zini There’s a $keyType property you need to set, so your model should look like this if you want to use UUIDs as primary keys:

class User extends Authenticatable
{
    protected $primaryKey = 'uuid';

    protected $keyType = 'string';

    public $incrementing = false;
}
1 like
Zini's avatar
Level 1

@martinbean Nice, it is more readable than the $cast syntax, but in the case of a database with the ability to generate uuids you shouldn't disable incrementing.

martinbean's avatar

@Zini True. The reason I included it was in my application I have a trait that generates UUIDs on model creation as opposed to leaving it to the database itself:

namespace App\Concerns;

use Ramsey\Uuid\Uuid;

trait IdentifiesUsingUuids
{
    public static function bootIdentifiesUsingUuids()
    {
        boot::creating(function ($model) {
            $model->setAttribute($model->getKeyName(), Uuid::uuid4());
        });
    }
}
namespace App\News;

use App\Concerns\IdentifiesUsingUuids;

class Article extends Model
{
    use IdentifiesUsingUuids;
}

Please or to participate in this conversation.