環境
Laravel Framework 8.54.0
PHP 8.0.9
docker-compose version 1.29.2
rorecek/laravel-ulid:^2.0
手順
rorecek/laravel-ulid
まずは、rorecek/laravel-ulid
のインストールを行います。
ターミナルを開き、以下のコマンドを入力します。
$ ./vendor/bin/sail composer require rorecek/laravel-ulid:^2.0
$ composer require rorecek/laravel-ulid:^2.0
これで、インストールは完了しました。
マイグレーション
次に、マイグレーションから編集していきます。
今回はユーザに関しての変更を行おうと思うので、
デフォルトのdatabase/migrations/2014_10_12_000000_create_users_table.php
を編集します。
ULIDは、26 文字の文字列になります。
そのため、以下のように編集します。
// ...
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
- $table->bigIncrements('id');
+ $table->char('id', 26)->primary();
// ...
});
}
// ...
}
モデル
最後にモデルを編集します。
オートインクリメントを無効にして、
id
を ULID で生成するように修正します。
trait
を用意してくれているので、
以下のように、変更すれば大丈夫です。
// ...
use Rorecek\Ulid\HasUlid;
class User extends Authenticatable
{
// ...
use HasUlid;
/**
* IDが自動増分されるか
*
* @var bool
*/
public $incrementing = false;
/**
* 自動増分IDの「タイプ」
*
* @var string
*/
protected $keyType = 'string';
// ...
}
これで、id
が ULID で生成されます。
注意点
上記までの手順で大枠は解決なのですが、
主キー(プライマリキー)をid
以外に設定しているときは上手く動作しません。
理由は、モデルの修正で使用したRorecek\Ulid\HasUlid
が影響しています。
中身を見てみると原因がハッキリします。
<?php
namespace Rorecek\Ulid;
trait HasUlid
{
protected static function bootHasUlid()
{
static::creating(function ($model) {
if (! $model->id) {
$model->id = \Ulid::generate();
}
});
static::saving(function ($model) {
$originalUlid = $model->getOriginal('id');
if ($originalUlid !== $model->id) {
$model->id = $originalUlid;
}
});
}
public function getIncrementing()
{
return false;
}
public function getKeyType()
{
return 'string';
}
}
そうなんです。
id
を直接指定してしまっているため、他のときは動かないようになってます。
解決方法
解決方法は、言葉にしてしまえば簡単ですが、
主キー(プライマリキー)が何のときでも動くようにしてあげればよいだけですね。
<?php
use Rorecek\Ulid\Facades\Ulid;
trait HasUlid
{
protected static function bootHasUlid()
{
static::creating(function (Model $model) {
if (! $model->getKey()) {
$model->setAttribute($model->getKeyName(), Ulid::generate());
}
});
static::saving(function (Model $model) {
$originalUlid = $model->getOriginal($model->getKeyName());
if ($originalUlid !== $model->getKey()) {
$model->setAttribute($model->getKeyName(), $originalUlid);
}
});
}
public function getIncrementing()
{
return false;
}
public function getKeyType()
{
return 'string';
}
/**
* IDが自動増分されるか
*
* @var bool
*/
public $incrementing = false;
/**
* 自動増分IDの「タイプ」
*
* @var string
*/
protected $keyType = 'string';
}
こんなtrait
を作成してあげれば、汎用的に使えると思います。
さいごに
ということで、rorecek/laravel-ulid
は
\Rorecek\Ulid\Facades\Ulid::generate()
とするだけで簡単にULIDを生成できるだけでなく、
主キー(プライマリキー)をULIDに変更する最低限の下地を既に作成してくれている訳です。
主キー(プライマリキー)を特別なものへと変更するにあたって、
created
やsaving
などのhook
に引っ掛けて特定の処理を行うことは常套手段でしたが、
毎回記述するのがとても煩わしかったのを覚えています。
なので、それも含めて準備してくれるのはとてもありがたい!!
あなたの実装ライフが少しでも楽になりますように~