A flexible way to generate permissions for resources.

For every app that requires managing roles and permissions, there's this problem of how do I generate and seed all the needed roles and permissions on every deployment, I'm gonna show you a neat way of doing just that.

Whenever I want to implement roles and permissions I always reach out to this awesome package by the good folks at Spatie, what I love about it is it's just an Eloquent model with some extra tricks hidden up its sleeve, so we can use the power of Eloquent to our advantage while maintaining the nice features of the package. Let's get to the code.

First, let's generate a seeder, php artisan make:seeder PermissionsSeeder, hoping inside the seeder class, we need a map to hold our resources and their available actions. defining available actions for each model is flexible because we can generate permissions for non-existing models, and we're not limited to the CRUD actions

protected $resources = [
'user' => ['view', 'create', 'update', 'delete'],
'post' => ['view', 'create', 'update'],
'announcement' => ['broadcast'],
];

We then need to loop through them and insert them in the database, I prefer to use updateOrCreate so that I can run the seeder whenever I want, knowing it won't try to add duplicate permissions

use Spatie\Permission\Models\Permission;
.
.
.
foreach ($resources as $resource => $actions) {
foreach ($actions as $action) {
Permission::updateOrCreate(['name' => "{$resource}:{$action}"]);
}
}

All good, now we have a list of permissions in the "resource:action" format, ex. announcement:broadcast.

One last thing to do, because the package caches the permissions for 24 hours, we need to bust the cache every time we run the seeder, we can add this call before the foreach above to do just so.

use Spatie\Permission\PermissionRegistrar;
.
.
.
app()[PermissionRegistrar::class]->forgetCachedPermissions();

We can use the same technique to seed our Roles if we need to. That would be it! would love to hear from you if you have a cleaner way.