Laravel-permission: Using UUID/GUID for primary key on user table

Created on 5 Oct 2017  路  13Comments  路  Source: spatie/laravel-permission

Not sure where to put this, but I am successfully using this using my UUID user IDs, in place of the integer IDs. Just wanted to document it publicly in case anyone else tries to do this.

I accomplished this by replacing every instance of $table->morphs('model') with:

$table->uuid('model_id');
$table->string('model_type');

I am using GUIDs because my main authentication is linked with Active Directory (via Adldap2/Adldap2-Laravel), and I need to use the AD primary keys as my primary keys to ensure user relation integrity to active directory.

Most helpful comment

I think there is something missing on the doc.

We need to update user model too.

class User extends Authenticatable
{
    ....

   // Add this 3 lines to override laravel default setting
    protected $primaryKey = 'id';
    public $incrementing = false;
    protected $keyType = 'string';

    ...
}

All 13 comments

Glad you got it working without any issues! Thanks for letting us know.

@AlexVanderbist can u add this to the docs ?

I think there is something missing on the doc.

We need to update user model too.

class User extends Authenticatable
{
    ....

   // Add this 3 lines to override laravel default setting
    protected $primaryKey = 'id';
    public $incrementing = false;
    protected $keyType = 'string';

    ...
}

@dashracer in my case it doesn't work with $incrementing = false . Only $keyType resolved the issue. Are you sure that $incrementing should be set to false according to UUID?

This is what I had to do in the top of my user model to make it work:

    public $incrementing = false;
    protected $primaryKey = 'guid';

@benyanke it's weird. Can you look at my issue: #824 ?

I have the same problem and I do not know how to solve ...
when I run assignRole it saves on db but generates an error...

Captura de Tela (3)
Captura de Tela (4)

when I run assignRole it saves on db but generates an error...

@miguelsmuller can you share your config/permission.php file contents?

@drbyte Hi, I'm having the same problem as @miguelsmuller when using assignRole. I'm using UUID as primary key. Here's my config/permission.php:

<?php

return [

    'models' => [

        /*
         * When using the "HasPermissions" trait from this package, we need to know which
         * Eloquent model should be used to retrieve your permissions. Of course, it
         * is often just the "Permission" model but you may use whatever you like.
         *
         * The model you want to use as a Permission model needs to implement the
         * `Spatie\Permission\Contracts\Permission` contract.
         */

        //'permission' => Spatie\Permission\Models\Permission::class,
        'permission' => \App\Models\Permission::class,

        /*
         * When using the "HasRoles" trait from this package, we need to know which
         * Eloquent model should be used to retrieve your roles. Of course, it
         * is often just the "Role" model but you may use whatever you like.
         *
         * The model you want to use as a Role model needs to implement the
         * `Spatie\Permission\Contracts\Role` contract.
         */

        //'role' => Spatie\Permission\Models\Role::class,
        'role' => \App\Models\Role::class

    ],

    'table_names' => [

        /*
         * When using the "HasRoles" trait from this package, we need to know which
         * table should be used to retrieve your roles. We have chosen a basic
         * default value but you may easily change it to any table you like.
         */

        'roles' => 'roles',

        /*
         * When using the "HasPermissions" trait from this package, we need to know which
         * table should be used to retrieve your permissions. We have chosen a basic
         * default value but you may easily change it to any table you like.
         */

        'permissions' => 'permissions',

        /*
         * When using the "HasPermissions" trait from this package, we need to know which
         * table should be used to retrieve your models permissions. We have chosen a
         * basic default value but you may easily change it to any table you like.
         */

        'model_has_permissions' => 'model_has_permissions',

        /*
         * When using the "HasRoles" trait from this package, we need to know which
         * table should be used to retrieve your models roles. We have chosen a
         * basic default value but you may easily change it to any table you like.
         */

        'model_has_roles' => 'model_has_roles',

        /*
         * When using the "HasRoles" trait from this package, we need to know which
         * table should be used to retrieve your roles permissions. We have chosen a
         * basic default value but you may easily change it to any table you like.
         */

        'role_has_permissions' => 'role_has_permissions',
    ],

    'column_names' => [

        /*
         * Change this if you want to name the related model primary key other than
         * `model_id`.
         *
         * For example, this would be nice if your primary keys are all UUIDs. In
         * that case, name this `model_uuid`.
         */

        'model_morph_key' => 'model_id',
    ],

    /*
     * When set to true, the required permission/role names are added to the exception
     * message. This could be considered an information leak in some contexts, so
     * the default setting is false here for optimum safety.
     */

    'display_permission_in_exception' => false,

    'cache' => [

        /*
         * By default all permissions are cached for 24 hours to speed up performance.
         * When permissions or roles are updated the cache is flushed automatically.
         */

        'expiration_time' => \DateInterval::createFromDateString('24 hours'),

        /*
         * The cache key used to store all permissions.
         */

        'key' => 'spatie.permission.cache',

        /*
         * When checking for a permission against a model by passing a Permission
         * instance to the check, this key determines what attribute on the
         * Permissions model is used to cache against.
         *
         * Ideally, this should match your preferred way of checking permissions, eg:
         * `$user->can('view-posts')` would be 'name'.
         */

        'model_key' => 'name',

        /*
         * You may optionally indicate a specific cache driver to use for permission and
         * role caching using any of the `store` drivers listed in the cache.php config
         * file. Using 'default' here means to use the `default` set in cache.php.
         */

        'store' => 'default',
    ],
];

Edit: I traced the code and the error happens on $model->load('roles') of HasRoles trait, line number 121.

        if ($model->exists) {
            $this->roles()->sync($roles, false);
            $model->load('roles');
        } else {
            $class = \get_class($model);

I tried to comment that line and no errors show when doing assignRole. I tried doing $user->load('roles'); inside php artisan tinker and it shows no error.

Also, I'm only getting the error inside my seeder. On tinker, when I do assignRole, no error occurs.

Last test is I added $user->refresh(); before assignRole and it did the trick.

Any ideas why is this happening?

Was any able to resolve this issue? I am experiencing the same thing as @miguelsmuller

I have tried $user->refresh(); with no luck. The error also gets thrown when I user $user->syncRoles.

Note that this error only occurs when I call I am call a new instance of User (creating a new user) I am able to update the users role with no issues.

Same issue as the last 2 people.

I'm having to comment out $model->load() in both the HasPermissions and HasRoles traits.

I replicated the 2 traits and called them within my User model, does anyone think this will cause issues other than making sure that I keep them up to date with any changes?

Can you explain what error is being thrown when $model->load() is called?

Understanding what the error is, and then digging into why that specific error is occurring, will lead to a better outcome.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

younus93 picture younus93  路  4Comments

enghelewa picture enghelewa  路  4Comments

hosseinnedaei picture hosseinnedaei  路  3Comments

bhulsman picture bhulsman  路  3Comments

NattananWs picture NattananWs  路  3Comments