michaeldyrynda / laravel-model-uuid

This package allows you to easily work with UUIDs in your Laravel models
MIT License
442 stars 46 forks source link

NULL being cast to UUID #105

Closed schmoove closed 2 years ago

schmoove commented 2 years ago

I have a schema that allows a UUID column to be set to NULL, but if I set this in the model, it seems a UUID is being generated anyway? This column also has a foreign key constraint, so a DB error is then thrown as there's no matching UUID.

I tried to use your very fine Nullable trait in conjunction but doesn't seem to work.

Example:

protected $nullable = [
        'nullable_uuid'
];

protected $casts = [
        'id' => EfficientUuid::class,
        'template_id' => EfficientUuid::class,
        'nullable_uuid' => EfficientUuid::class,
        'options' => 'array',
        'created_at' => 'datetime',
    ];

How can get around this, and prevent a UUID from being generated?

schmoove commented 2 years ago

Think I've found the problem – in GeneratesUuid.php, the strtolower() line needs to be within the isset() && !is_null() block:

if (isset($model->attributes[$item]) && !is_null($model->attributes[$item])) {                    
    /* @var \Ramsey\Uuid\Uuid $uuid */
    try {
        $uuid = Uuid::fromString(strtolower($model->attributes[$item]));
    } catch (InvalidUuidStringException $e) {
        $uuid = Uuid::fromBytes($model->attributes[$item]);
    }
}

$model->{$item} = strtolower($uuid->toString());

Currently it's skipping the NULL field as it should, but the strtolower line is still setting the UUID after that block. Does that look right?

michaeldyrynda commented 2 years ago

The if block is there to use the existing value if it is set i.e. you explicitly set a UUID, otherwise generate a new one, then lower the value.

This package ensures that a UUID is always set for the marked fields.