spatie/laravel-permission

team_id doesn't have a default value

mauritskorse opened this issue · 5 comments

Describe the bug
SQL error when creating a new role using the teams functionality: the field team_id has no default value defined.

Versions
You can use composer show to get the version numbers of:

  • spatie/laravel-permission package version: 6.3.0
  • laravel/framework package: 10.41

PHP version: 8.2.3

Database version: mariadb 10.11.6

To Reproduce
When using the teams function right from the beginning (so not from by using php artisan permission:setup-teams afterwards I have a migration that causes an error when trying to create a new global role using:

// with null team_id it creates a global role; global roles can be assigned to any team and they are unique
Role::create(['name' => 'writer', 'organisation_id' => null]);

The error I get is

QLSTATE[HY000]: General error: 1364 Field 'organisation_id' doesn't have a default value (Connection: mysql, SQL: insert into `roles_user_has_roles` (`model_id`, `model_type`, `role_id`) values (1, User, 1))

(i have changed the default team_id to organisation_id in the config, and the user model has an organisation_id field)

When looking at the stub for the migration when adding the teams functionality afterwards (add_teams_fields.php.stub), there are some differences:
On model_has_permissions and model_has_roles table the team_foreign_key gets a default value of 1, while the main stub I had installed did not provide this:

- $table->unsignedBigInteger($columnNames['team_foreign_key']);
+ $table->unsignedBigInteger($columnNames['team_foreign_key'])->default('1');

When applying this change to my migration file, I stop getting the error, however, the role is set to an organisation and not globally.

Another way I got this to work is to set these columns to be nullable, and remove the column from the primary keys:

$table->unsignedBigInteger($columnNames['team_foreign_key'])->nullable(); //->default(1);

$table->primary(
    [
        // $columnNames['team_foreign_key'], // this column is nullable and cannot be a primary key
        $pivotPermission,
        $columnNames['model_morph_key'],
        'model_type'
    ],
    'model_has_permissions_permission_model_type_primary'
);

For now I go with the last fix.
Since I am just starting with this package, I am not sure whether this is the best way.

insert into roles_user_has_roles

roles_user_has_roles?

Yes, that is on the roles table.
But on the other two tables (model_has_permissions and model_has_roles), it was not defined in the stub:

$table->unsignedBigInteger($columnNames['team_foreign_key']);

$table->unsignedBigInteger($columnNames['team_foreign_key']);

And in the other stub a default was set:

$table->unsignedBigInteger($columnNames['team_foreign_key'])->default('1');

$table->unsignedBigInteger($columnNames['team_foreign_key'])->default('1');

insert into roles_user_has_roles

roles_user_has_roles?

Ah, yes, I had my tables prefixed ;) With a default config it is user_has_roles

That is the expected behavior, global roles must be assigned by organization, that means the same role could be assigned to many organizations, but not in all automatically
This is so that a group of permissions can be reused across multiple organizations.