For many years I have used michaeldyrynda/laravel-model-uuid without any issues. Its a great package that served me well. But since version 9 Laravel has native support for uuids. So today let do the long overdue migration.
Changes to your eloquent models
- Change the trait from
use Dyrynda\Database\Support\GeneratesUuid;to
use Illuminate\Database\Eloquent\Concerns\HasUuids;- Change the cast from
Dyrynda\Database\Support\Casts\EfficientUuidto
Illuminate\Database\Eloquent\Casts\AsBinaryIf you are still using the property, also migrate to using a function like so:
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'uuid' => AsBinary::uuid(),
];
}
- Add a function to configure the uuid field as a unique identifier
/**
* Get the columns that should receive a unique identifier.
*
* @return array<int, string>
*/
public function uniqueIds(): array
{
return ['uuid'];
}
$table->efficientUuid in migrations
In order to keep using the efficientUuid helper in your migrations you can add the following to the boot function of your AppServiceProvider
Blueprint::macro('efficientUuid', function (string $columnName) {
return $this->binary($columnName, length: 16, fixed: true);
});whereUuid scope
If you still want to make use of the whereUuid helper that Michael Dyrynda's package provided you'll have to implement it yourself. You can do this by extending the HasUuids trait and adding a helper function. In the example below there are 2 options:
- Convert the string uuid to binary in PHP. This will make your code a little more flexible against different databases.
- Convert the string uuid to binary in MySQL. This will offload the calculation to your MySQL. If you have no specific reason to convert in PHP, use this one.
<?php
namespace App\Traits;
use Ramsey\Uuid\Uuid;
use Illuminate\Support\Str;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Concerns\HasUuids as Base;
trait HasUuids
{
use Base;
/**
* @param array<string>|string $uuid
*/
public function scopeWhereUuid(Builder $query, $uuid): Builder
{
$uuids = is_array($uuid) ? $uuid : [$uuid];
return $this->convertInMysql($query, $uuids);
}
private function convertInPhp(Builder $query, array $uuids): Builder
{
if (empty($uuids)) {
return $query->whereRaw('0 = 1');
}
$uuids = array_map(function ($uuid) {
return Uuid::fromString($uuid)->getBytes();
}, $uuids);
$placeholders = implode(', ', array_fill(0, count($uuids), '?'));
return $query->whereRaw(
"uuid IN ({$placeholders})",
$uuids
);
}
private function convertInMysql(Builder $query, array $uuids): Builder
{
$uuids = array_filter($uuids, function ($uuid) {
return Str::isUuid($uuid);
});
if (empty($uuids)) {
return $query->whereRaw('0 = 1');
}
$placeholders = implode(', ', array_fill(0, count($uuids), 'UUID_TO_BIN(?)'));
return $query->whereRaw(
"uuid IN ({$placeholders})",
$uuids
);
}
}