Easily use UUIDs in Laravel
Tags: php, laravel, uuids
Published: 2018-10-29 00:00:00

---
title: "Easily use UUIDs in Laravel"
description: "You might be used to using a common auto incrementing integer as your primary column, but using something like UUIDs is super easy in Laravel."
author: "Wilbur Powery"
date: "2018-10-29"
tags: [php, laravel, uuids]
published: true
---

First published on my [website](https://wilburpowery.co/posts/easy-uuids-in-laravel/)

## What are UUIDs?

UUID stands for **Universal Unique Identifier**. It's a 128-bit number used to uniquely identify some object or in our case, a record in our database.

I won't go into depth about the pros or cons of UUIDs when compared to a regular auto incrementing ID, that's an entire blog post of its own. What I will do, is show you how easy it is to use UUIDs in your Laravel application if you wish too.

## Prepare your migration

The first step of using UUIDs in your database is setting up your column to be of a specific type. By default, a Laravel migration includes a `$table->primary('id');` column in each migration you create.

Using UUIDs is as simple as updating our migration to use the `->uuid()` method that Laravel provides out of the box for us. For example, let's say we're creating a migration to describe the schema of a Post.

```php
Schema::create('posts', function (Blueprint $table) {
    $table->uuid('id')->primary();
    $table->string('title');
    $table->text('body');
    $table->timestamps();
});
```

The important line you should notice is this one: `$table->uuid('id')->primary();`. Notice we are using the `uuid()` method instead of the common `increments()` method. As you can see, the `uuid()` method specifies the column should be a UUID equivalent column and we also specify that  it should be the primary key on the table.

## Creating the UUID

If you run `php artisan migrate`, and try to create a new record using something like a factory, or manually creating it, you'll run into an error saying the `id` column cannot be null.

When using the `primary()` method on our migrations, Laravel will notice it's an auto-incrementing column and whip it up for us. But, since we switched over to using UUIDs, we'll need to create the ID ourselves. 

###   Use Eloquent Model Events

Since you're using Laravel, I imagine you would also be using Eloquent to easily interact with your database. 

Eloquent has what are known as Model Events. In total, it fires a total of 11 events in different scenarios. You have  the following events: 
- `retrieved`
- `creating`
- `created`
- `updating`
- `updated`
- `saving`
- `saved`
- `deleting`
- `deleted`
- `restoring`
- `restored`.

If you want to learn more about Eloquent Events, you can find their documentation [here](https://laravel.com/docs/5.7/eloquent#events).

Now, back to creating our UUIDs. Let's take a look at how your `Post` model could look like:

```php
class Post extends Model
{
    protected $guarded = []; // YOLO
  
    protected static function boot()
    {
        parent::boot();

        static::creating(function ($post) {
            $post->{$post->getKeyName()} = (string) Str::uuid();
        });
    }

    public function getIncrementing()
    {
        return false;
    }

    public function getKeyType()
    {
        return 'string';
    }
}
```

Our Model has 3 methods in it. The `boot` method is where we can hook into our model and listen for any Eloquent events. The `getIncrementing` method is used by Eloquent to now if the IDs on the table are incrementing. Remember we are using UUIDs so we set auto incrementing to `false`.
Lastly, the `getKeyType` method just specifies that the IDs on the table should be stored as strings.

In our `boot` method, we are listening for the `creating` Eloquent event. This even is fired just before the record is actually stored in the database. We hook into this event, and use the `uuid()` method provided by the `Str` class in Laravel.

A while ago, people might have installed a package with Composer in order to generate a UUID but you can generate them easily using the `uuid()` method provided by the class.

Easy as that, you can use UUIDs in Laravel. 

As I final note, I'll usually have a PHP trait called `UsesUuid` where I'll have the logic above. That way I wouldn't repeated the code on every model I wanted to use UUIDs.

This is what the `UsesUuid` trait would look like:

```php
<?php

namespace App\Models\Concerns;

use Illuminate\Support\Str;

trait UsesUuid
{
    protected static function bootUsesUuid()
    {
        static::creating(function ($model) {
            if (! $model->getKey()) {
                $model->{$model->getKeyName()} = (string) Str::uuid();
            }
        });
    }

    public function getIncrementing()
    {
        return false;
    }

    public function getKeyType()
    {
        return 'string';
    }
}
```

Notice how everything is more generalized and not tied to a unique model.

Now, in any model that as the correct column in its migration you can simply use the `UsesUuid` trait like so:

```php
class Post extends Model
{
  use App\Models\Concerns\UsesUuid;
  
  protected $guarded = []; // YOLO
}
```

That's it. In just a few simple steps you got UUIDs working in your Laravel app.