Need to conditionally load user permissions (abilities) via eloquent as flattened array
Description
Hi, I need to be able to load "abilities" for a user within my system as a flattened array. Note that a User isn't always the logged in user and is sometimes a tenant of the system. Right now I'm doing this with an appended attribute, but this is loaded everywhere and is calling the Lazy load error.
How can I reproduce the following function but via eloquent when doing User::all() in the system:
/**
* Get permissions for user
*/
public function getAbilitiesAttribute(): array
{
try {
return $this->getAllPermissions()->pluck('name')->flatten()->toArray();
} catch (\Exception $err) {
}
return [];
}
Steps To Reproduce
n/a
Example Application
n/a
Version of spatie/laravel-permission package:
6.10.1
Version of laravel/framework package:
11.38.2
PHP version:
8.3.8
Database engine and version:
MySQL 8
OS: Windows/Mac/Linux version:
ac
Not an issue, must be a discussion
@parallels999 Okay, but still my discussion is still a valid point, how might we achieve this functionality with the package to reduce and optimise the number of queries. Maybe this could be a new feature?
@sts-ryan-holton You mentioned that part of the concern you raised is related to lazy-loading.
Does the lazy-loading issue resolve when using v6.13.0 (Ref: #2776 ) ?
Just eager load relations
User::with(['roles', 'roles.permissions', 'permissions'])->all();
Now abilities should be available without lazy load errors
This appears to work without errors:
public function getAbilitiesAttribute(): array
{
try {
return $this
->loadMissing(['roles', 'roles.permissions', 'permissions'])
->getAllPermissions()->pluck('name')->flatten()->toArray();
} catch (\Exception $err) {
}
return [];
}
I don't want to load it everywhere via my User model though. What I'm saying is that's an inefficient way of doing it but works for now since the package doesn't seem to provide a flattened approach to doing it, say, within a controller directly. How do I achieve this?
I don't want to load it everywhere via my User model though.
Do you mean that you'd just prefer that this package build it into the trait, so that it becomes part of the User model?
that's an inefficient way of doing it but works for now since the package doesn't seem to provide a flattened approach to doing it, say, within a controller directly.
Can you give an example of how you'd use this in a controller?
Third, what would be the "ideal" interface that you have in mind?
Dear contributor,
because this issue seems to be inactive for quite some time now, I've automatically closed it. If you feel this issue deserves some attention from my human colleagues feel free to reopen it.