RailsBlog

Using UUID as Primary Key on Hyperf

How to create a base class for creating models on Hyperf that use UUID as a primary key

FaboBorgesLima ·

Creating the migration

You can create the migration using the hyperf binary (bin/hyperf.php) like you would do normally:

./bin/hyperf.php gen:migration create_your_models_table

After that you will to modify the migration to something like that:

<?php

use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('your_models', function (Blueprint $table) {

            # $table->id('id');
            $table->uuid('id')->primary();
            # your columns that you want to create
            $table->datetimes();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('your_models');
    }
};

Downloading the UUID lib

For downloading the UUID lib execute this command on your project:

composer require ramsey\uuid

Creating your base model

You could pretty easily turn this abstract class into a trait, but i like more abstract classes:

<?php

declare(strict_types=1);

// i created on lib, but you can create this model anywhere
namespace App\Lib;

use Ramsey\Uuid\Uuid;
use Hyperf\DbConnection\Model\Model;

abstract class ModelUUID extends Model
{
    protected string $keyType = 'string';

    /**
     * Indicates if the IDs are auto-incrementing.
     *
     * @var bool
     */
    public bool $incrementing = false;

    protected function initialize(): void
    {
        if (!$this->id) {
            $this->id = (string) Uuid::uuid4();
        }
    }

    public function save(array $options = []): bool
    {
        $this->initialize();
        return parent::save($options);
    }

    public static function create(array $attributes = [])
    {
        $model = new static($attributes);
        $model->initialize();
        $model = $model->save() ? $model : null;
        return $model;
    }
}

and then, finally create your model :


declare(strict_types=1);

namespace App\Model;


/**
 * @property string $id 
 * @property \Carbon\Carbon $created_at 
 * @property \Carbon\Carbon $updated_at 
 */
class YourModel extends ModelUUID
{
    /**
     * The table associated with the model.
     */
    protected ?string $table = 'your_models';

    /**
     * The attributes that are mass assignable.
     */
    protected array $fillable = [];

    /**
     * The attributes that should be cast to native types.
     */
    protected array $casts = [
        'id' => 'string',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
    ];
}