Skip to content

Instantly share code, notes, and snippets.

@jewei
Created September 4, 2022 10:03
Show Gist options
  • Save jewei/bc0c134dffb8cec141556205e0ffca03 to your computer and use it in GitHub Desktop.
Save jewei/bc0c134dffb8cec141556205e0ffca03 to your computer and use it in GitHub Desktop.
Implementation of Ordered Binary UUID as Database Primary Key for Laravel 9
<?php
namespace App\Models\Traits;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
use Ramsey\Uuid\Uuid;
trait HasBinaryUuidPrimaryKey
{
public static function bootHasBinaryUuidPrimaryKey(): void
{
static::creating(function ($model) {
$model->uuid = Uuid::fromString($model->attributes['uuid'] ?? Str::orderedUuid())->getBytes();
});
}
public function getKeyName(): string
{
return 'uuid';
}
public function getKeyType(): string
{
return 'string';
}
public function getIncrementing(): bool
{
return false;
}
public function getRouteKeyName(): string
{
return 'uuid';
}
public function resolveRouteBinding($value, $field = null): Model
{
return self::whereUuid($value, $field)->firstOrFail();
}
public function scopeWhereUuid(Builder $query, $uuid, ?string $field = null): Builder
{
$uuid = Uuid::fromString($uuid)->getBytes();
if ($field) {
return $query->whereIn($this->qualifyColumn($field), $uuid);
}
return $query->whereKey($uuid);
}
public function uuid(): Attribute
{
return Attribute::make(
get: fn ($value) => Uuid::fromBytes($value),
);
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->char('uuid', 16)->charset('binary');
$table->string('title');
$table->timestamps();
$table->primary('uuid');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
};
<?php
namespace App\Models;
use App\Models\Traits\HasBinaryUuidPrimaryKey;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
use HasBinaryUuidPrimaryKey;
/**
* The attributes that are mass assignable.
*
* @var array<string>
*/
protected $fillable = [
'uuid',
'title',
];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment