Using ULID in Laravel Framework

Using ULID in Laravel Framework

In a previous post, we talked about how ULID can be a better choice for primary keys in MySQL than UUIDs. In this tutorial, we will go over how to use ULID in Laravel Framework.

ULID has been supported in Laravel since v9.30.1 and has received some improvements in later releases So no third-party packages are needed to use it.

Eloquent Models

Let's take an Article model as an example. First, we create the article's model and migration file as we normally do

php artisan make:model Article

In the up method inside the migration file, the table's primary key will be defined using the ulid method followed by the primary method.

public function up(): void
{
    Schema::create('articles', function (Blueprint $table) {
        $table->ulid('id')->primary();
        $table->string('title');
        $table->text('body');
        $table->timestamps();
    });
}

What the ulid method does is create a column of type CHAR and set its length to 26 bytes instead of the 36 bytes needed for UUIDs.

Then in the Article eloquent model, the Illuminate\Database\Eloquent\Concerns\HasUlids trait will be added

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Concerns\HasUlids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Article extends Model
{
    use HasFactory, HasUlids;
}

Laravel also has a method in the Illuminate\Database\Schema\Blueprint class for creating foreign keys that references a table with ULID primary key.

In our example, we can add a Comment model and each comment belongs to one Article. The foreign key of the articles table is defined using the foreignUlid method

public function up(): void
{
    Schema::create('comments', function (Blueprint $table) {
        $table->uuid('id')->primary();
        $table->string('body');
        $table->foreignUlid('article_id')->constrained();
        $table->timestamps();
    });
}

And the last method is ulidMorphs that create the columns needed for a polymorphic relation. Let's add another Tag model that can be linked to many models not just Article. The taggables table can be defined like this:

public function up(): void
{
    Schema::create('taggables', function (Blueprint $table) {
        $table->foreignUlid('tag_id')->constrained();
        $table->ulidMorphs('taggable');
    });
}

Str Facade

ULID can be created anywhere in your app using the ulid method in the Illuminate\Support\Str facade.

Str::ulid()->toBase32()

The above statement returns the ULID and it will look something like this 01H0WXWP3XGAX0ZJVG7Q2E70FC.

Finally, if you are interested in the implementation being used to generate ULID, check out the Symfony UID component that Laravel uses.