Eloquent UUIDs.
Tags: laravel, uuid, php
Published: 2018-04-10 09:15:30

---
title: Eloquent UUIDs.
published: true
description: Learn how, and why you should be using UUIDs for your Eloquent models
tags: laravel, uuid, php
cover_image: https://thepracticaldev.s3.amazonaws.com/i/mbmnhjun2c5vfsan4ok0.png
---


In this tutorial, I'm going to show you how and why to use `uuid`s as your primary keys in your eloquent models.

## What are UUIDs?

A Uuid (Unique universal identifier) is a 128bit number used to identify information on the internet. Depending on the specific mechanisms used, a UUID is either guaranteed to be different or is, at least, extremely likely to be different from any other UUID generated until 3400 A.D (that means for more than the next thousand years, it's highly unlikely that the same UUID would be generated again no matter the mechanism used). 

UUIDs are therefore important specifically because of their uniqueness. 

## Why should we use UUIDs?

- UUIDs do not reveal information about your database records, so it's safer to use them in a public URL. For example, seeing `/users/12/` in the URL strongly suggests that a user with an id of 11 exists, which greatly increases the possibility of attack.
- They are unique across tables, databases, and servers, and therefore migration from one database to another is incredibly easy.
- UUIDs are generated anywhere, and therefore you can know the unique identifier of the next database record without necessarily hitting your database.

## Integrating UUIDs into your eloquent models.

We'll start by installing a fresh laravel application.

```bash
    laravel new eloquent-uuids
```

### Generating UUIDs

The first thing we'll do is set up a way to generate a UUID.
The first option would be to use an external package that does this for us, and I'll recommend [this package](https://github.com/ramsey/uuid).Personally, I'll rather just have a custom function that does this, so from the [PHP documentation](http://php.net/manual/en/function.uniqid.php#94959), we'll get a function that generates UUIDs for us. 

```php

<?php

function uuid4()
{
    return sprintf(
        '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
        mt_rand(0, 0xffff),
        mt_rand(0, 0xffff),
        mt_rand(0, 0xffff),
        mt_rand(0, 0x0fff) | 0x4000,
        mt_rand(0, 0x3fff) | 0x8000,
        mt_rand(0, 0xffff),
        mt_rand(0, 0xffff),
        mt_rand(0, 0xffff)
    );
}

```

Now, where do we place this file in our laravel application? I'll create a new file in `/app/Helpers/uuid.php`, and I'll place this function in it.

Next, I'll autoload this file with composer so that this function would be globally available in my laravel application.

```json
// composer.json
...
    "autoload": {
        "files": [
            "App/Helpers/uuid.php"
        ]
    }
...

```

### Disabling default primary key system in laravel

To disable the default way primary keys works:

 - Replace the `increments` field for id with a string field.
```php
// database\migrations\create_users_table.php
Schema::create('users', function (Blueprint $table) {
  $table->string('id');
  $table->string('name');
  $table->string('email')->unique();
  $table->string('password');
  $table->rememberToken();
  $table->timestamps();
});

```

- Set the `incrementing` property on the model to `false`:

```php

// App\User.php

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

```

### Registering eloquent `creating` hook

On the model, we will register a `creating` hook, which laravel will execute before making a database query to save the record.

```php
// App\User.php

/**
 * Boot the Model.
 */
 public static function boot()
 {
    parent::boot();

    static::creating(function ($instance) {
       $instance->id = uuid4();
    });
 }

```

That's it ! Anytime we create a new database record of the `User` model, a UUID is generated and automatically saved into the database for it.

To test this out, I added a simple route, to create a user and return the newly created user.

```php

// routes/web.php

Route::get('/', function () {
    return \App\User::create([
        'name' => 'bahdcoder',
        'email' => 'bahdcoder@gmail.com',
        'password' => bcrypt('password'),
    ]);
});


```

If we check this out in the browser, we have this json response:

```json

{
  "name": "bahdcoder",
  "email": "bahdcoder@gmail.com",
  "id": "c784692b-c7ea-4d76-9d5a-409df46d4cae",
  "updated_at": "2018-04-09 19:13:27",
  "created_at": "2018-04-09 19:13:27"
}

```
Great! Automagically our UUID was generated when creating the User model. 

### Extra

Having to do this for all of your models would be a lot of duplication, so we could have a custom base model, that inherits from laravel's base model, and all of our models are going to extend from this one. So let's create a custom `Model.php` in our `app` directory:

```php

// app/Model.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model as BaseModel;

class Model extends BaseModel
{
    /**
     * Indicates if the IDs are auto-incrementing.
     *
     * @var bool
     */
    public $incrementing = false;

    /**
     * Boot the Model.
     */
    public static function boot()
    {
        parent::boot();

        static::creating(function ($instance) {
            $instance->id = uuid4();
        });
    }
}


```

Therefore for any further models created, they will extend this new `app\Model.php`.

- Do not forget to change the `$table->increments('id');` in your migrations to `$table->string('id');`.