Giter Site home page Giter Site logo

laravel-eloquent-uuid's Introduction

Eloquent UUID

GitHub stars

GitHub tag (latest SemVer) Build status Packagist PHP from Packagist Packagist

Introduction

A simple drop-in solution for providing UUID support for the IDs of your Eloquent models.

Both v1 and v4 IDs are supported out of the box, however should you need v3 or v5 support, you can easily add this in.

Installing

Reference the table below for the correct version to use in conjunction with the version of Laravel you have installed:

Laravel This package
v5.8.* v1.*
v6.* v6.*
v7.* v7.*
v8.* v8.*
v9.* v9.*
v10.* v10.*

You can install the package via composer:

composer require goldspecdigital/laravel-eloquent-uuid:^10.0

Usage

There are two ways to use this package:

  1. By extending the provided model classes (preferred and simplest method).
  2. By using the provided model trait (allows for extending another model class).

Extending model

When creating a Eloquent model, instead of extending the standard Laravel model class, extend from the model class provided by this package:

<?php

namespace App\Models;

use GoldSpecDigital\LaravelEloquentUUID\Database\Eloquent\Model;

class BlogPost extends Model
{
    //
}

Extending user model

The User model that comes with a standard Laravel install has some extra configuration which is implemented in its parent class. This configuration only consists of implementing several interfaces and using several traits.

A drop-in replacement has been provided which you can use just as above, by extending the User class provided by this package:

<?php

namespace App\Models;

use GoldSpecDigital\LaravelEloquentUUID\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    //
}

Using trait

As an alternative to extending the classes in the examples above, you also have the ability to use the provided trait instead. This requires a more involved setup process but allows you to extend your models from another class if needed:

<?php

namespace App\Models;

use GoldSpecDigital\LaravelEloquentUUID\Database\Eloquent\Uuid;
use Illuminate\Database\Eloquent\Model;

class BlogPost extends Model
{
    use Uuid;
    
    /**
     * The "type" of the auto-incrementing ID.
     *
     * @var string
     */
    protected $keyType = 'string';

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

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $guarded = [];
}

Generating UUIDs

If you don't specify the value for the primary key of your model, a UUID will be automatically generated. However, if you do specify your own UUID then it will not generate one, but instead use the one you have explicitly provided. This can be useful when needing the know the ID of the model before you have created it:

// No UUID provided (automatically generated).
$model = Model::create();
echo $model->id; // abb034ae-fcdc-4200-8094-582b60a4281f

// UUID explicity provided.
$model = Model::create(['id' => '04d7f995-ef33-4870-a214-4e21c51ff76e']);
echo $model->id; // 04d7f995-ef33-4870-a214-4e21c51ff76e

Specifying UUID versions

By default, v4 UUIDs will be used for your models. However, you can also specify v1 UUIDs to be used by setting the following property/method on your model:

When extending the class

<?php

namespace App\Models;

use GoldSpecDigital\LaravelEloquentUUID\Database\Eloquent\Model;

class BlogPost extends Model
{
    /**
     * The UUID version to use.
     *
     * @var int
     */
    protected int $uuidVersion = 1;
}

When using the trait

<?php

namespace App\Models;

use GoldSpecDigital\LaravelEloquentUUID\Database\Eloquent\Uuid;
use Illuminate\Database\Eloquent\Model;

class BlogPost extends Model
{
    use Uuid;

    /**
     * The UUID version to use.
     *
     * @return int
     */
    protected function uuidVersion(): int
    {
        return 1;
    }
}

Support for v3 and v5

Should you need support for v3 or v5 UUIDs, you can simply override the method which is responsible for generating the UUIDs:

<?php

namespace App\Models;

use GoldSpecDigital\LaravelEloquentUUID\Database\Eloquent\Model;
use Ramsey\Uuid\Uuid;

class BlogPost extends Model
{
    /**
     * @throws \Exception
     * @return string
     */
    protected function generateUuid(): string
    {
        // UUIDv3 has been used here, but you can also use UUIDv5.
        return Uuid::uuid3(Uuid::NAMESPACE_DNS, 'example.com')->toString();
    }
}

Creating models

In addition of the make:model artisan command, you will now have access to uuid:make:model which has all the functionality of the standard make:model command (with exception of not being able to create a pivot model):

php artisan uuid:make:model Models/Post --all

Database migrations

The default primary ID column used in migrations will not work with UUID primary keys, as the default column type is an unsigned integer. UUIDs are 36 character strings so we must specify this in our migrations:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('users', function (Blueprint $table): void {
            // Primary key.
            $table->uuid('id')->primary();
        });
    }
}

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('posts', function (Blueprint $table): void {
            // Primary key.
            $table->uuid('id')->primary();
        
            // Foreign key.
            $table->uuid('user_id');
            $table->foreign('user_id')->references('id')->on('users');
        });
    }
}

Running the tests

To run the test suite you can use the following command:

composer test

Contributing

Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests to us.

Versioning

We use SemVer for versioning. For the versions available, see the tags on this repository.

Authors

See also the list of contributors who participated in this project.

License

This project is licensed under the MIT License - see the LICENSE.md file for details.

laravel-eloquent-uuid's People

Contributors

bytestream avatar matthew-inamdar avatar ricuss avatar svenluijten avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

laravel-eloquent-uuid's Issues

Release for Laravel ^v6.0

With the new version of Laravel being released, we need to release a new version of the package which supports ^v6.0.

Since Laravel has also switched to semantic versioning, the major version of the package should now match the version of Laravel it supports for simplicity.

UUID on pivot

hi,
is there a way of creating uuid on pivot?
on seeding, I'm getting General error: 1364 Field 'id' doesn't have a default value

my model is..

use GoldSpecDigital\LaravelEloquentUUID\Database\Eloquent\Model;
class BoardPost extends Model
{
    use Uuid;
    
    public $incrementing = false;
    protected $keyType = 'string';
    protected $primaryKey = 'id';
    
    public static function boot()
    {
        parent::boot();
        self::creating(function ($model) {
            $uuid = (string) Uuid::generate(4);
            $model->id = $uuid;
        });
    }
}

Is there anyway to provide default uuid v1?

Is there anyway to default to other versions of uuid? Instead of creating uuid v4 create uuid v1?
This is just out of curiosity? Apache usergrid uuid default is v1 so if you would like to build something over that this would be great.

General error: 20 datatype mismatch

Hi there, i have this problem with sqlite:

SQLSTATE[HY000]: General error: 20 datatype mismatch (SQL: insert into "users" ("name", "role", "email", "password", "id", "updated_at", "created_at") values (Fern, superuser, Fern@d
ash.com, $2y$10$LjnVxgcMpuQZWrFErSKDmOeJND8yMLnMJ2vFQ7QfqQRABz8T22NQK, cf0de48c-3472-4ee2-be4a-2828f5c9b882, 2020-05-16 02:45:28, 2020-05-16 02:45:28))

I think that sqlite not support this ??

MustVerifyEmail not working

When using the laravel "MustVerifyEmail", with the "GoldSpecDigital\LaravelEloquentUUID\Foundation\Auth\User" the user is still able to log in even without confirming their emails.

Alternative trait instead of extending class

Following the proposal of #20, we should definitely add a trait as an alternative to extending the classes provided.

This flexibility allows this package to still be utilised in the event that the client code is already extending their models from a class provided in another package.

This will need to be documented in the README.md.

Create UUID in seeder

How can I create UUID in seeder file?

Sample

       DB::table('brands')->delete();

        $brands = array(
            array(
                'id' => '',  // how to create this?
                'name' => 'No Brand',
                'slug' => 'no-brand',
                'description' => null,
                'photo' => null,
                'created_at' => Carbon::now()->format('Y-m-d H:i:s'),
                'updated_at' => Carbon::now()->format('Y-m-d H:i:s'),
            ),
        );
        
        DB::table('brands')->insert($brands);

Duplicate

Hello,

there is a security against duplicates ?

Laravel 9

I see that there is already a pull request to support Laravel 9 #47.
Any estimates on when this will be merged and published?

Thank you for your work!

Postgres / uuid-ossp extension

I’m using Postgres with the uuid-ossp extension which provides the following functionality: uuid_generate_v4() which I have created a macro on the schematic builder for:

Blueprint::macro('primaryUuid', function ($field = 'uuid') {
    $this->uuid($field)->default(\DB::raw('uuid_generate_v4()'))->primary();
});

This requires the $incrementing property on the model to be true (incrementing is a bad choice for this property on Laravel’s side, it basically means “the database handles it”)

Might I suggest that this model utilises the uuid_generate_v4 method to create the UUID for Postgres if the option is available?

Might it be better to create a macro for creating primary UUID columns and add it to the schema builder which sets a default value for a primary UUID?

If this is something you would want to try I could make a PR for it.

Add artisan command

An artisan command should be provided which creates a model using this class. If possible, we should have this override the standard Laravel command - and it should be configurable so you can choose whether to override it or not.

uuid:make:model fails in case sensitive filesystems

When running uuid:make:model in a Linux system, a FileNotFoundException is raised.

The code looks for a 'stubs' directory (with lowercase 's'), and the directory src/Console/Stubs (with uppercase 's') is not found. A simple solution would be changing this directory to a lowercase name.

Laravel 7 Support

Composer refuses to install this with Laravel 7.

Hopefully you can fix it. Don't think anything has changed or needs to be fixed, just the dependency version check needs to be fixed. :)

Laravel 8 Compatibility

Hi, as of Laravel 8 is out, I can't upgrade my project because it's not compabitible with goldspecdigital/laravel-eloquent-uuid.
If possible, can you create a new release?

Missing documentation for migrations table

Great package! I'm just missing some documentation on how the migrations table should look like.

I used to use:

$table->uuid('user_id');

But I am getting error:

SQLSTATE[01000]: Warning: 1265 Data truncated for column 'user_id' at row 1

When inserting data. I assume this is because of a wrong type?

relationship model uuid

I have relationship table that connects 2 other tables together (let say post _tags) this table only gets id of post and id of tags therefore this table does not have model (doesn't need one), now when I store my post tags with sync() method. It leaves id column empty which cause errors while storing my posts.

Any solution to that?

Event::fake() in tests prevents uuid being automatically generated

Set up a feature test with the following (after setting up the uuid in the User model as per the documentation).

    /** @test */
    public function a_user_can_be_created()
    {
        Event::fake();

        $user = \App\User::create([
            'name' => 'J Smith',
            'email' => '[email protected]',
            'password' => 'some_pass',
        ]);

         dd($user->id);
    }

Will result in an SQL error:

PDOException: SQLSTATE[HY000]: General error: 1364 Field 'id' doesn't have a default value

Remove the Event::fake(); line and it works as expected, outputting the user's uuid.

Is there a way to use this and still use the event fakes in tests?

419 Page Expired

After changing my users table to use uuid when I try to register it says

419
Page Expired

Has anyone else experienced this? what should I do?

Schema::create('users', function (Blueprint $table) {
            $table->uuid('id')->primary(); <-- here
            $table->string('name');
            // rest of it...
}
use GoldSpecDigital\LaravelEloquentUUID\Database\Eloquent\Uuid; <-- here

class User extends Authenticatable
{
    use HasApiTokens;
    use HasFactory;
    use HasProfilePhoto;
    use Notifiable;
    use TwoFactorAuthenticatable;
    use Uuid; <-- here
    protected $keyType = 'string'; <-- here
    public $incrementing = false; <-- here
}

doesn't work with method 'with'

This lib doesn't work with function 'with'
for example Dataset::with('keywords')->get();

return

SQLSTATE[42883]: Undefined function: 7 ERROR: operator does not exist: uuid = integer LINE 1: ..."keyword_id" where "dataset_keyword"."dataset_id" in (0, 61,... ^ HINT: No operator matches the given name and argument types. You might need to add explicit type casts. (SQL: select "keyword".*, "dataset_keyword"."dataset_id" as "pivot_dataset_id", "dataset_keyword"."keyword_id" as "pivot_keyword_id", "dataset_keyword"."order" as "pivot_order" from "keyword" inner join "dataset_keyword" on "keyword"."id" = "dataset_keyword"."keyword_id" where "dataset_keyword"."dataset_id" in (0, 61, 6, 0, 0) order by "order" asc)

Backport Uuid trait to Laravel v5.8

Hi there,

Am I right if I think the Uuid trait is not available for laravel 5.8.* (using v1.1.0)?
Would it be possible to backport this? Or are there specific reasons to not go there? :)

Thanks,
Glenn

$guarded must be array

Hi! On version ^8.0 I'm getting an error:

Type of GoldSpecDigital\LaravelEloquentUUID\Database\Eloquent\Model::$guarded must be array 
(as in class Illuminate\Database\Eloquent\Model)

Integrity constraint violation: 19 NOT NULL

Hi there,

I have tried the package, but this error not present in normal model insertion

SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: client_service.id (SQL: insert into "client_service" ("client_id", "detail", "service_id", "start", "user_id") values (e5cbdc0c-e23c-4df3-9908-a1a52de45311, VDSVDS, d50c2578-75d7-4b96-b8d7-c960e624734a, 2020-05-16 00:00:00, 3f7d6572-3135-4d62-8d63-a03e7a5a363b))

the code if u want see:

    /**
     * @param Request $request
     * @return \Illuminate\Http\RedirectResponse
     */
    public function create(Request $request)
    {
        $request->validate([
            'id' => 'max:255|exists:clients',
            'service_id' => 'max:255|required|exists:services,id',
            'start' => 'max:255',
            'detail' => 'max:255',
        ]);

        \App\Client::find($request->id)->services()
            ->attach($request->service_id, [
                'user_id' => auth()->id(),
                'start' => Carbon::parse(str_replace('/', '-', $request->start))->toDate(),
                'detail' => $request->detail ?? '',
            ]);

        return back()->with('success', __('Service has been created'));
    }

i have restored normal id for the moment.. tel me updates

Create Custom Column (ID)

I have an issue for when custom id create when booting method
"Declaration of App\Http\Core\Helper\Helpers::boot() must be compatible with GoldSpecDigital\LaravelEloquentUUID\Database\Eloquent\Model::boot(): void"
I thought that it is a feature and can implement for manually created for custom Id at the model class with Trait. I hope you add this feature to the next released version.

Support binary uuid

String comparison of UUID is least recommended due to infamous cycles of comparison as compared to integer.
Support article - Optimised UUID Storage

Currently recommended repository Laravel Efficient UUID be referred more of to get an idea of implementation.

Although not many repositories yet support uuid alternative as key identification of data, hence above alternative repository seemed more helpful. (They also have a normal uuid repo too.)

I loved your ease of usage over their repo, hence suggesting their ideology and your accessibility, together, will be a big charm.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.