Git Product home page Git Product logo

laravel-efficient-uuid's Introduction

Laravel Efficient UUIDs

Build Status Latest Stable Version Total Downloads License Buy us a tree

Introduction

This package extends the default grammar file for the given MySQL connection adding an efficientUuid blueprint method that creates a binary(16) field.

As of 3.0, this package no longer overrides Laravel's default uuid method, but rather adds a separate efficientUuid field, due to compatibility issues with Laravel Telescope (#11).

As of 4.0, this package uses a custom cast to provide casting functionality into your models.

Note: This package purposely does not use package discovery, as it makes changes to the MySQL schema file, which is something you should explicitly enable.

MySQL, SQLite, and PostgreSQL are the only supported connection types, although I welcome any pull requests to implement this functionality for other database drivers.

Note that doctrine/dbal does not appear to support changing existing uuid fields, and doing so would cause your existing values to be truncated in any event.

For more information, check out this post on storing and working with UUID in an optimised manner.

Using UUIDs in Laravel is made super simple in combination with laravel-model-uuid. Note that when using laravel-model-uuid, if you are not casting your UUIDs or calling the query builder directly, you'll need to use the getBytes method when setting the UUID on the database, otherwise your values will be truncated. Depending on your MySQL/MariaDB configuration, this may lead to application errors due to strict settings. See (#1) for more information.

This package is installed via Composer. To install, run the following command.

composer require dyrynda/laravel-efficient-uuid

Register the service provider in your config/app.php configuration file:

'providers' => [
    ...
    Dyrynda\Database\LaravelEfficientUuidServiceProvider::class,
],

Migrations

There is nothing special needed for this to function, simply declare a uuid column type in your migration files. If you plan on querying against the UUID column, it is recommended that you index the column, but avoid making it the primary key.

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

Casting

You will need to add a cast to your model when using laravel-model-uuid in order to correctly set and retrieve UUID from your MySQL database with binary fields.

<?php

namespace App;

use Dyrynda\Database\Casts\EfficientUuid;
use Dyrynda\Database\Support\GeneratesUuid;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use GeneratesUuid;

    protected $casts = [
        'uuid' => EfficientUuid::class,
    ];
}

Querying by UUID

If you want to find a record by a string UUID, you need to use scope:

Post::whereUuid('25b112a9-499a-4627-9ea0-72cd8694aee3')->first();

Validation

Should you wish to use the efficient UUID column as part of your validation strategy, you may use the EfficientUuidExists rule as normal.

use Dyrynda\Database\Rules\EfficientUuidExists;

public function update(Request $request, User $user)
{
    $request->validate([
        // Using the default column name
        'uuid' => [new EfficientUuidExists(Post::class)],

        // Using a custom column name
        'custom_uuid' => [new EfficientUuidExists(Post::class, 'custom_uuid')],
    ]);
}

Support

If you are having general issues with this package, feel free to contact me on Twitter.

If you believe you have found an issue, please report it using the GitHub issue tracker, or better yet, fork the repository and submit a pull request.

If you're using this package, I'd love to hear your thoughts. Thanks!

Treeware

You're free to use this package, but if it makes it to your production environment you are required to buy the world a tree.

It’s now common knowledge that one of the best tools to tackle the climate crisis and keep our temperatures from rising above 1.5C is to plant trees. If you support this package and contribute to the Treeware forest you’ll be creating employment for local families and restoring wildlife habitats.

You can buy trees here

Read more about Treeware at treeware.earth

laravel-efficient-uuid's People

Contributors

aallport avatar afshiney avatar aidask avatar billriess avatar bitbirddev avatar boryn avatar chapeupreto avatar craigsansam avatar defenestrator avatar hrobertson avatar jamesmills avatar joelmellon avatar joshuabehrens avatar laravel-shift avatar lloricode avatar maxcelos avatar michaeldyrynda avatar richardstyles avatar schnoop avatar wimwidgets 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

laravel-efficient-uuid's Issues

how to use efficientUuid inside a $factory

Hello guys,
i'm not sure how to use efficientUuid inside a factory to generate a new uuid for db testing, i always get call to undefined function efficientUuid ()
` <?php

use Dyrynda\Database\Casts\EfficientUuid;
use Faker\Generator as Faker;

$factory->define(App\Partner::class, function (Faker $faker) {
return [
'name' => $faker->company,
'email' => $faker->companyEmail,
'uuid' => efficientUuid(),
'created_at' => now(),
'updated_at' => now(),
];
}); `
any sample code would be appreciated..
thank you

EfficcientUuid and SQL errors: Malformed UTF-8 characters

Hey.
Thank you for your package. Really nice.

I faced a problem that was getting me crazy for a few hours because the error I was getting was somewhat unexpected. And I believe it was caused by efficient-uuid.

My "Organization" table/model has a field called "slug". For some other reason, my trait that should automatically generate the slug value was not working. Anyway, when I was saving my model, I was just doing this:

public function store(CreateOrganizationRequest $request)
    {
        $params = $request->all();
        $params['owner_id'] = $request->user()->id;

        $organization = Organization::create($params);

        return response()->json($organization, 201, [], JSON_UNESCAPED_UNICODE);
    }

So, this should fail because "slug" is a required field and it's not being informed anywhere. Something like "slug is a required column and there is no default value" or something like that from the SQL or Laravel. But the error I got was:

{
    "message": "Malformed UTF-8 characters, possibly incorrectly encoded",
    "exception": "InvalidArgumentException",
    "file": "/path-to/project/backend-laravel/vendor/laravel/framework/src/Illuminate/Http/JsonResponse.php",
    "line": 88,
    "trace": [
        {
            "file": "/path-to/project/backend-laravel/vendor/symfony/http-foundation/JsonResponse.php",
            "line": 54,
            "function": "setData",
            "class": "Illuminate\\Http\\JsonResponse",
            "type": "->"
        },
        {
            "file": "/path-to/project/backend-laravel/vendor/laravel/framework/src/Illuminate/Http/JsonResponse.php",
            "line": 32,
            "function": "__construct",
            "class": "Symfony\\Component\\HttpFoundation\\JsonResponse",
            "type": "->"
        },

So, the problem here is: when the model fails to be saved, I believe that Laravel is trying to convert the binary error with json_encode() and. because of the binary column, another exception is thrown, regarding the bad encoding. Is that anything we could do here? If not, could we update the README file so other users would be aware that this "Malformed UTF-8 characters, possibly incorrectly encoded" may be some missing required fields when saving a model to DB?

I'm also not very sure if this issue should be here or in laravel-model repo.

Cheers.

Prepare for laravel 9

Laravel 9 is around the corner, would be good to start preparing for it!

It currently fails to install on dev branch (laravel new sample --dev)

Custom resolveRouteBinding method

Hi!

Can we have an optional custom resolveRouteBinding method on GeneratesUuid trait?

Would be nice to easily use route binding to models in controllers.

Here is a simple code example:

class Post extends Model
{
    use GeneratesUuid;

    // Default model binding behavior without this attribute or if it is false
    protected $bindUuid = true;
    ...
trait GeneratesUuid
{

    public function resolveRouteBinding($value, $field = null)
    {
        if (isset($this->bindUuid) && $this->bindUuid === true)
            return $this->whereUuid($value)->first();
        else
            return parent::resolveRouteBinding($value, $field);
    }

Php 8 support

Hello,

Getting error in php 8 as bellow:

- Root composer.json requires dyrynda/laravel-efficient-uuid ^4.2 -> satisfiable by dyrynda/laravel-efficient-uuid[4.2.0].
- dyrynda/laravel-efficient-uuid 4.2.0 requires php ^7.3 -> your php version (8.0.0) does not satisfy that requirement.

Best way to handle nullable uuid column

I have a question on how would be the best way to deal with a nullable uuid column.
I was adding UUID support to a very old project and so I thought to add the uuid column as nullable so to generate the UUIDs after the migration since I was not planning to use the UUIDs immediately, but for a later change.

I added the column as follows:

$table->efficientUuid('uuid')->nullable()->index();

Then I created a command to run in a job at a later stage to grab all the entities without a UUID set and generate it. Maybe with a bit of overthinking I used $entity->uuid to check if the UUID was set before generating a new one, as new entities might have been generated before the command could run. In other words I wanted to prevent generating a new UUID for an entity that already has one.

Turn out I was getting an error in the EfficientUuid class

[TypeError]
Argument 1 passed to Ramsey\Uuid\Uuid::fromBytes() must be of the type string, null given, called in /var/www/vendor/dyrynda/laravel-efficient-uuid/src/Casts/EfficientUuid.php on line 20

Exception trace:
  at /var/www/vendor/ramsey/uuid/src/Uuid.php:386
 Ramsey\Uuid\Uuid::fromBytes() at /var/www/vendor/dyrynda/laravel-efficient-uuid/src/Casts/EfficientUuid.php:20
 Dyrynda\Database\Casts\EfficientUuid->get() at 
 /var/www/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php:572

And in fact the location is exactly the line when I was reading $entity->uuid to check if it was valid

Uuid::isValid($entity->uuid);

My approach to solve the problem was to sub-class the EfficientUuid cast class and return null in case the value was null. So the main question is this approach correct and should be this null check done within the library or was just my scenario to generate this unexpected behavior?

Of course I can submit a pull request to add this check, but I wanted to understand if was something acceptable that the library should do.

Request regarding package discovery

Hey @michaeldyrynda

I would like to confirm that you have no plans to add in service provider autoloading to the composer.json of this package. Such as...

"extra": {
        "laravel": {
            "providers": [
                "Dyrynda\\Database\\LaravelEfficientUuidServiceProvider"
            ]
        }
    }

My hope and desire is to conditionally load this package in my own package service provider. I want to give the developer using my packages the ability to decide if they use binary(16) storage or not.

Just need some peace of mind and all that.

Efficient UUID for foreign keys

Hi,

I am currently experimenting with foreign keys being uuids instead of ids and I was wondering if this package have any support for that.

The problem I am facing is when I have a belongsToMany relationship and try to eager load it using with('tags'), it returns empty results.

I couldn't find any info on that so far.

Laravel 5.8 Support

Please add support for Laravel 5.8. I am trying to install this package when using Laravel 5.8, but fails since this package only supports up till 5.7.

Cheers! Sacha

Usage with Telescope

When using Telescope with this package, Telescope will not work, failing with a String data, right truncated: 1406 Data too long for column 'batch_id' at row 1 error. This is because the Telescope models do not cast their uuids to binaries, and are storing the string value in the database.

Best workaround seems to use the new feature migration-customization (from v1.0.11, jan 28th). By publishing the migration files and manually changing the type from uuid to char(36) in all cases, Telescope will work again.

$table->char('uuid', 36);

Just a heads-up for others running into this issue.

Model save not casting UUID to binary?

Thank you for the great package. I'm struggling with a persisting issue and wondering what I'm missing.
If I simply load a record from a model, change a property, and then save it, I get this exception:

b"SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'template_id' at row 1 (SQL: update documentsettemplate_id= fb3c3189-9e96-4283-98e2-f5f8e114370c,document.updated_at= 2022-03-10 20:48:38 whereid = §\x15cÍõ8M>Åeì¯k╗╚e)"

So the id is being cast correctly, but not the template_id. Thanks for your help.

Model:

public function uuidColumns(): array
    {
        return ['id', 'template_id'];
    }

protected $casts = [
        'id' => EfficientUuid::class,
        'template_id' => EfficientUuid::class
    ];

Controller:

$document = Document::whereUuid($id, 'id')->first();
$document->status = 'CANCELLED';
        try {
            $document->save();
        } catch (\Exception $e){
            dd($e->getMessage());
        }

UUID not generated when using Eloquent Upsert

UUID is not being generated when using the Upsert. I'm trying to insert a data that is not yet existing on my table.

EloquentModel::upsert(
    [
        [
            'type' => 'all',
            'name' => "All"
        ]
    ],
    ['type']
)

I've tried to use the DB but I'm getting an error

{
    "error": {
    "message": {
        "message": "Array to string conversion",
        "file": "/app/vendor/laravel/framework/src/Illuminate/Support/Str.php@596"
    },
    "status_code": 500
    }
}

SQLite Support

Not so much of an issue, more of a question.

Since I use more often SQLite than MySQL, I am using currently Spatie's package for UUID's as it supports SQLite. I had a look at your package and can perhaps help you with adding support for SQLite.

One quick question I have is regarding the LaravelEfficientUuidServiceProvider. At the moment it is tightly couple to MySQL and if SQLite would be added, how do you think having different options available should work? Would it be an approach that this package provides a configuration so users can set with DB backend they are using?

What are your thoughts?

Cheers! Sacha

uuid v4 vs ordered (v6)

I have a question and I would like to know your opinion.

I have a model with id as the primary key and uuid as the secondary key (I use unique instead of index), noting that all my external calls, that is, calls via API, I use uuid to identify the record, so I wonder, is it more efficient to use standard version 4 or version 6 (ordered)? Because I imagine the following, despite the uuid column being indexed, when making a request via API using uuid as an identifier, the database still needs to look for it in the index records, it would not be easier for the database to find this record if were "ordered"?

DB: MySQL/MariaDB

Laravel 11 compatibility

Your requirements could not be resolved to an installable set of packages.

Problem 1
- dyrynda/laravel-efficient-uuid 5.0.0 requires illuminate/contracts ^10.0 -> found illuminate/contracts[v10.0.0, ..., v10.48.4] but these were not loaded, likely because it conflicts with another require.
- dyrynda/laravel-efficient-uuid[4.5.0, ..., 4.5.3] require illuminate/contracts ^8.12|^9.0 -> found illuminate/contracts[v8.12.0, ..., v8.83.27, v9.0.0, ..., v9.52.16] but these were not loaded, likely because it conflicts with another require.
- dyrynda/laravel-efficient-uuid[4.3.0, ..., 4.4.0] require illuminate/container ^8.12 -> found illuminate/container[v8.12.0, ..., v8.83.27] but these were not loaded, likely because it conflicts with another require.
- dyrynda/laravel-efficient-uuid 4.2.0 requires php ^7.3 -> your php version (8.2.12) does not satisfy that requirement.
- dyrynda/laravel-efficient-uuid[4.0.0, ..., 4.1.1] require php ^7.2.5 -> your php version (8.2.12) does not satisfy that requirement.
- dyrynda/laravel-efficient-uuid[3.0.0, ..., 3.1.0] require php ^7.2 -> your php version (8.2.12) does not satisfy that requirement.
- dyrynda/laravel-efficient-uuid 2.3.0 requires illuminate/container ~5.4 -> found illuminate/container[v5.4.0, ..., v5.8.36] but these were not loaded, likely because it conflicts with another require.
- dyrynda/laravel-efficient-uuid 2.2.0 requires illuminate/container 5.4.* || 5.5.* || 5.6.* || 5.7.* -> found illuminate/container[v5.4.0, ..., v5.7.28] but these were not loaded, likely because it conflicts with another require.
- dyrynda/laravel-efficient-uuid 2.1.0 requires illuminate/container 5.4.* || 5.5.* || 5.6.* -> found illuminate/container[v5.4.0, ..., v5.6.39] but these were not loaded, likely because it conflicts with another require.
- dyrynda/laravel-efficient-uuid 2.0.0 requires illuminate/container 5.4.* || 5.5.* -> found illuminate/container[v5.4.0, ..., v5.5.44] but these were not loaded, likely because it conflicts with another require.
- dyrynda/laravel-efficient-uuid 1.0.0 requires illuminate/container 5.4.* -> found illuminate/container[v5.4.0, ..., v5.4.36] but these were not loaded, likely because it conflicts with another require.
- Root composer.json requires dyrynda/laravel-efficient-uuid * -> satisfiable by dyrynda/laravel-efficient-uuid[1.0.0, 2.0.0, 2.1.0, 2.2.0, 2.3.0, 3.0.0, 3.0.1, 3.1.0, 4.0.0, ..., 4.5.3, 5.0.0].

You can also try re-running composer require with an explicit version constraint, e.g. "composer require dyrynda/laravel-efficient-uuid:*" to figure out if any version is installable, or "composer require dyrynda/laravel-efficient-uuid:^2.1" if you know which you need.

Installation failed, reverting ./composer.json and ./composer.lock to their original content.

how to generate a new Uuid using efficientUuid()

Hello there,
it is unclear to me on how to generate a new uuid for my test unit, can you please share an example?

   factory(App\User::class)->create([
        'id' => 1,
        'name' => 'Admin',
        'uuid' => efficientUuid('uuid'),
    ]);

gives an error???
thank you .

Doesn't work with PostgreSQL 12

I'm using the latest v4.0.1 version of the package on Laravel 7.
I'm also using PostgreSQL 12.

When I try to migrate, I get this error:

Method Illuminate\Database\Schema\Grammars\PostgresGrammar::typeEfficientUuid does not exist.

Its probably because of this line expects the postgres name for driver, but Laravel 7 uses pgsql as driver name.

I tried to change the name to pgsql, but then I get this error:

   Illuminate\Database\QueryException

SQLSTATE[22021]: Character not in repertoire: 7 ERROR:  invalid byte sequence for encoding "UTF8": 0x90
(SQL: insert into "users" ("name", "email", "email_verified_at", "password", "remember_token", "status",
"uuid", "organization_id", "updated_at", "created_at") values (Prof. Johnny Torphy, [email protected],
2020-06-25 12:02:06, $2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi, ejdCIBmyNS, 1,
 ��G�|D��*���C�, ?, 2020-06-25 12:02:06, 2020-06-25 12:02:06) returning "id")

  at vendor/laravel/framework/src/Illuminate/Database/Connection.php:671
    667|         // If an exception occurs when attempting to run a query, we'll format the error
    668|         // message to include the bindings with SQL, which will make this exception a
    669|         // lot more helpful to the developer instead of just the database's errors.
    670|         catch (Exception $e) {
  > 671|             throw new QueryException(
    672|                 $query, $this->prepareBindings($bindings), $e
    673|             );
    674|         }
    675|

cc @defenestrator

Default value for uuid column

Looking for a way to make easy to insert data using a graphic interface like TablePlus or Workbench.

I'm testing setup the default value for uuid column to auto generate the binary uuid so we can just leave it black like the id:

$table->efficientUuid('uuid')->index()->default(\Illuminate\Support\Facades\DB::raw('(uuid_to_bin(uuid()))'));

Does anyone uses it or see any problem?

Screen Shot 2021-12-29 at 08 07 01

Macro return type

The efficientUuid blueprint macro is very helpful. In combination with Laravel IDE Macros it also gets recognized by my IDE. The chaining of the index() method is not recognized however, because the macro has no return type. Therefore my IDE thinks it returns void when instead it should return a Illuminate\Database\Schema\ColumnDefinition, as the addColumn method from Blueprint does.

So please add the return type to the macro closure. I don't know if the connection resolver closures have a similar issue, but it might be nice to also add return types to those.

Backwards Compatibility for Laravel 6

Hi there,

Is there a version or option for installation into Laravel 6? Currently working on projects that are in Laravel 6 due to LTS support, and looking at using this package to help solve some issues with UUIDs

Could you recommend a release that can be used in Laravel 6, or could you make some updates that will allow backwards compatibility for Laravel 6 please? This is quite urgent for us so could there be a swift reply please?

Thanks,
DuShaun

Changing column definition in migration fails with `Unknown column type "efficientuuid" requested`

I try to change the column definition in a migration:

$table->efficientUuid('uuid')->nullable(false)->change();

I get this error when running the migration:

Unknown column type "efficientuuid" requested. Any Doctrine type that you use has to be registered with \Doctrine\DBAL\Types\Type::addType(). You can get a list of all the known types with \Doctrine\DBAL\Types\Type::getTypesMap(). If this error occurs during database introspection then you might have forgotten to register all database types for a Doctrine Type. Use AbstractPlatform#registerDoctrineTypeMapping() or have your custom types implement Type#getMappedDatabaseTypes(). If the type name is empty you might have a problem with the cache or forgot some mapping information.

Models with (Efficient) Uuid PK cannot be lazy loaded

Disclaimer: I know it's not recommended to use Laravel Model Uuids / Efficient Uuids as PK. I would happily discuss the situation if you open for a quick architectural debate, but let's keep the following example short. Err kinda.

Imagine I have three tables:

  • Carts have a unique customer id.
  • CartGroups: each Cart might have multiple CartGroups
  • Partners: each CartGroup is representing a Partner (aka seller or shop) in the customer's Cart.

Carts and CartGroups are native to the microservice (API) that handles them, they have unsigned BigInt ids (as PK). Partners, on the other hand, come from a different service and stored as-is for caching purposes. They have EfficientUuid ids, therefore CartGroups have an EfficientUuid foreign key (partnerId) pointing to them.

Migration files:

        Schema::create('partners', function (Blueprint $table) {
            $table->efficientUuid('id')->primary();
            $table->string('name', 255);
            $table->string('logoUrl', 255);
            $table->timestamps();
        });

        Schema::create('carts', function (Blueprint $table) {
            $table->id();
            $table->char('customerId', 40)->unique();
            $table->timestamps();
        });

        Schema::create('cartGroups', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('cartId');
            $table->efficientUuid('partnerId');
            $table->timestamps();

            $table->foreign('cartId')->references('id')->on('carts')
                ->cascadeOnDelete()
                ->cascadeOnUpdate();

            $table->foreign('partnerId')->references('id')->on('partners')
                ->cascadeOnDelete()
                ->cascadeOnUpdate();
        });

Model definitions:

class Partner extends Model
{
    use GeneratesUuid;

    public $incrementing = false;

    protected $keyType = 'string';

    protected $table = 'partners';

    protected $fillable = ['id', 'name','logoUrl'];

    protected $casts = [
        'id' => EfficientUuid::class,
    ];

    public function uuidColumns(): array
    {
        return ['id'];
    }
}


class Cart extends Model
{
    protected $table = 'carts';

    protected $fillable = ['customerId'];

    public function cartGroups(): HasMany
    {
        return $this->hasMany(CartGroup::class, 'cartId')->orderBy('id');
    }
}


class CartGroup extends Model
{
    protected $table = 'cartGroups';

    protected $fillable = ['cartId', 'partnerId'];

    protected $casts = [
        'partnerId'  => EfficientUuid::class,
    ];

    public function uuidColumns(): array
    {
        return ['partnerId'];
    }

    public function cart(): BelongsTo
    {
        return $this->belongsTo(Cart::class, 'cartId');
    }

    public function partner(): BelongsTo
    {
        return $this->belongsTo(Partner::class, 'partnerId');
    }
}

A simple controller to fetch a complete Cart (with all relations using with) for a given customerId:

class GetCartController
{
    public function __invoke(string $customerId): JsonResponse
    {
        return new JsonResponse([
            'data' => Cart::query()
                ->with(['cartGroups.partner'])
                ->where('customerId', $customerId)
                ->firstOrFail()
        ]);
    }
}

Tables are seeded with the following data:

INSERT INTO `partners` (`id`, `name`, `logoUrl`, `created_at`, `updated_at`) VALUES
(UNHEX('624A5B9B62F351CE8E3C0D25BD61AA11'), 'X Shop', 'x_logo.jpg', '2023-03-29 21:32:08', '2023-03-29 21:32:08'),
(UNHEX('ACAD4FC645AF5C47A7A9D69FE069AFAD'), 'Y Shop', 'y_logo.jpg', '2023-03-29 21:32:08', '2023-03-29 21:32:08');

INSERT INTO `carts` (`id`, `customerId`, `created_at`, `updated_at`) VALUES
(1, 'abc123', '2023-03-29 21:32:08', '2023-03-29 21:32:08');

INSERT INTO `cartGroups` (`id`, `cartId`, `partnerId`, `created_at`, `updated_at`) VALUES
(1, 1, UNHEX('624A5B9B62F351CE8E3C0D25BD61AA11'), '2023-03-29 21:32:08', '2023-03-29 21:32:08'),
(2, 1, UNHEX('ACAD4FC645AF5C47A7A9D69FE069AFAD'), '2023-03-29 21:32:08', '2023-03-29 21:32:08');

This is the result (without timestamps):

{
  "data": {
    "id": 1,
    "customerId": "abc123",
    "cart_groups": [
      {
        "id": 1,
        "cartId": 1,
        "partnerId": "624a5b9b-62f3-51ce-8e3c-0d25bd61aa11",
        "partner": null
      },
      {
        "id": 2,
        "cartId": 1,
        "partnerId": "acad4fc6-45af-5c47-a7a9-d69fe069afad",
        "partner": null
      }
    ]
  }
}

And these are the generated queries as observed by Telescope:

select * from `carts` where `customerId` = 'abc123' limit 1

select * from `cartGroups` where `cartGroups`.`cartId` in (1) order by `id` asc

select * from `partners` where `partners`.`id` in (
    '624a5b9b-62f3-51ce-8e3c-0d25bd61aa11',
    'acad4fc6-45af-5c47-a7a9-d69fe069afad'
  )

So no Partners loaded as the query uses uuids as string instead of binary.

Spent the day looking for others with similar problems and possible solutions, haven't found any, unfortunately. I'm not sure how to proceed, as I'm fairly new to Laravel / Eloquent. Also I understand this might be a feature request for a very narrow use case, but I'd happily implement it myself, if you'd be so kind to point me the right direction. ;)

Cheers.

Validation error when checking if model exists using UUID

I encountered an issue with validating form fields with UUIDs.

When validating if a value exists in the UUID column using the standard method,
public function rules() { return [ 'model_uuid' => 'exists:models,uuid' ]; }

or performing a check using

$model->where('uuid', $uuid)->exists()

the result is false, even if the value actually exists, due to the difference between binary and string representation. The string uuid value is not automatically converted to the binary representation when performing the check.

I had to work around this by creating a custom rule, which uses the Uuid::import() method provided by the webpatser/laravel-uuid package:

use Illuminate\Contracts\Validation\Rule;
use Illuminate\Support\Facades\DB;
use Webpatser\Uuid\Uuid;

class ExistsUuid implements Rule
{

    private $table;

    /**
     * Create a new rule instance.
     *
     * @param $table
     */
    public function __construct($table)
    {
        $this->table = $table;
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        return DB::table($this->table)->where('uuid',  Uuid::import($value)->bytes)->exists();
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'This :attribute does not exist!';
    }
}

Used in a validator
'model_uuid' => [new ExistsUuid('models')]

I have two (three?) questions:

  1. Is there a better workaround or built-in method to achieve this?
  2. If not, can it be implemented?
  3. If not, I think this should be mentioned in the readme.

Thanks!

`Malformed UTF-8 characters` error when a QueryException is thrown

I've faced the same problem described here and here (but that package has been abandoned).

The problem occurs because the exception can't be formatted to normal JSON data since it contains binary. The problem can be solved by doing these changes in illuminate\database\QueryException.php:

$this->message = $this->formatMessage($sql, $bindings, $previous);

To:

$this->message = utf8_encode($this->formatMessage($sql, $bindings, $previous));

But it's defiantly not a good idea. Any idea about solving it?

String data, right truncated: 1406 Data too long for column 'uuid'

using the repo in conjunction with your other laravel-model-uuidrepo. But I am getting the following error:

SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'uuid' at row 1 (SQL: insert into...

This happens when I try to run a seeder:

         DB::table('pages')->insert([
            [
                'uuid' => Uuid::uuid4()->toString(),
                'parent_id' => 0,...

I ma using a local Ubuntu 16.04 local server, running MariaDB/MySQL 10.1.

I think it's to do with adding the Schema::defaultStringLength(191);.

Is there a way around / fix this that I can implement.

Model with binary UUID can't be used in a Laravel Queue payload

dispatch(new MyJob(ModelWithBinaryUuid::create())) fails with:

message: "Unable to JSON encode payload. Error code: 5"
exception: "Illuminate\Queue\InvalidPayloadException"
file: "/vendor/laravel/framework/src/Illuminate/Queue/Queue.php"
line: 91

This is a know issue documented in laravel/framework#15235 and laravel/framework#12194. Laravel's Queue uses json_encode() which doesn't call model's toJson() method. Because of that https://github.com/michaeldyrynda/laravel-model-uuid/blob/79b20e5b2d6cae7b64e45858ea9202b7f26975a6/src/GeneratesUuid.php#L167-L175 is not called.

I don't have any good ideas how to solve it without modifying the Laravel's Queue code. Would be nice to add a note to docs about it, so people using this package don't have to do the research I did. My workaround will be to not pass the whole model to the Queue but only the attributes I need.

Method Illuminate\Database\Schema\Blueprint::efficientUuid does not exist.

Running Migration with use of package gives Method Illuminate\Database\Schema\Blueprint::efficientUuid does not exist. error.

  • Installed via composer
  • Added provider to providers in config/app.php
  • Modified migrations to use efficientUuid column
  • Run migrations and am met with that error.

Maybe I'm missing something, as no one else seems to have hit this error, but this fundamentally doesn't work.
The efficientUuid Blueprint macro is seemingly not registered...

Using Laravel V8.
package version 4.2

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.