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 ·

Using UUIDs on Hyperf

This is a quick guide on how to use UUIDs as primary keys on Hyperf. It covers the migration, the model and the trait you can reuse across all your models.

Download the ramsey/uuid package (default UUID generator)

Ramsey/uuid is the default UUID generator used by Hyperf's HasUuids trait and the default UUID generator for most PHP applications. You can install it using Composer:

composer require ramsey/uuid

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');

    }

};

Creating the HasUuid trait

Hyperf ships with a built-in HasUuids concern, but it doesn't generate the UUID when creating the Model on the DB. Create the following trait once and reuse it across all your models:


<?php

declare(strict_types=1);

namespace Shared\Model\Trait;

use Hyperf\Database\Model\Builder;

use Hyperf\Database\Model\Concerns\HasUuids;

trait HasUuid
{
    use HasUuids;

    /**
     * Generate UUIDs for unique-id columns before inserting.
     */
    protected function performInsert(Builder $query): bool
    {
        foreach ($this->uniqueIds() as $column) {
            if (empty($this->getAttribute($column))) {
                $this->setAttribute($column, $this->newUniqueId());
            }
        }

        return parent::performInsert($query);
    }
}

Creating your model

Use the HasUuid trait directly in your model. No base class needed:


<?php

declare(strict_types=1);

namespace App\Model;

use Hyperf\DbConnection\Model\Model;

use Shared\Model\Trait\HasUuid;

/**

 * @property string $id

 * @property \Carbon\Carbon $created_at

 * @property \Carbon\Carbon $updated_at

 */

class YourModel extends Model

{

    use HasUuid;

    /**

     * 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',

    ];

}