2026-06-15 21:09:49 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Models\V5;
|
|
|
|
|
|
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
|
|
|
|
|
|
|
|
|
abstract class V5Model extends Model
|
|
|
|
|
{
|
2026-07-06 15:40:37 +00:00
|
|
|
/**
|
|
|
|
|
* Whether the model's table has a `uuid` column. Models without one (set
|
|
|
|
|
* this to false there) skip public-id generation and route on the primary
|
|
|
|
|
* key instead.
|
|
|
|
|
*/
|
|
|
|
|
protected bool $hasUuidColumn = true;
|
|
|
|
|
|
2026-07-02 19:26:41 +00:00
|
|
|
public function getRouteKeyName(): string
|
|
|
|
|
{
|
2026-07-06 15:40:37 +00:00
|
|
|
return $this->hasUuidColumn ? 'uuid' : $this->getKeyName();
|
2026-07-02 19:26:41 +00:00
|
|
|
}
|
|
|
|
|
|
2026-06-19 09:44:42 +00:00
|
|
|
protected static function boot(): void
|
|
|
|
|
{
|
|
|
|
|
parent::boot();
|
|
|
|
|
|
2026-07-06 15:40:37 +00:00
|
|
|
static::creating(function (self $model): void {
|
|
|
|
|
if ($model->hasUuidColumn && ! $model->getAttribute('uuid')) {
|
|
|
|
|
$model->setAttribute('uuid', $model->newUniquePublicId());
|
2026-06-19 09:44:42 +00:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
2026-07-06 15:40:37 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Generate a public id, regenerating (up to three candidates) when one is
|
|
|
|
|
* already taken. A concurrent insert between this exists() check and our
|
|
|
|
|
* own insert can still collide; the unique index then rejects the insert,
|
|
|
|
|
* which is an acceptable residual race for these cheap, retryable writes.
|
|
|
|
|
*/
|
|
|
|
|
protected function newUniquePublicId(): string
|
|
|
|
|
{
|
|
|
|
|
$attempts = 0;
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
$candidate = $this->newPublicIdCandidate();
|
|
|
|
|
$attempts++;
|
|
|
|
|
} while (
|
|
|
|
|
$attempts < 3
|
|
|
|
|
&& $this->newModelQuery()->where('uuid', $candidate)->exists()
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return $candidate;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected function newPublicIdCandidate(): string
|
|
|
|
|
{
|
|
|
|
|
return new_public_id();
|
|
|
|
|
}
|
2026-06-15 21:09:49 +00:00
|
|
|
}
|