Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Need to conditionally load user permissions (abilities) via eloquent as flattened array #2793

Open
sts-ryan-holton opened this issue Jan 21, 2025 · 8 comments

Comments

@sts-ryan-holton
Copy link

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

@parallels999
Copy link
Contributor

Not an issue, must be a discussion

@sts-ryan-holton
Copy link
Author

@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?

@parallels999
Copy link
Contributor

laravel-permission Features

@drbyte
Copy link
Collaborator

drbyte commented Feb 5, 2025

@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 ) ?

@parallels999
Copy link
Contributor

parallels999 commented Feb 5, 2025

Just eager load relations

User::with(['roles', 'roles.permissions', 'permissions'])->all();

Now abilities should be available without lazy load errors

@drbyte
Copy link
Collaborator

drbyte commented Feb 16, 2025

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 [];
    }

@sts-ryan-holton
Copy link
Author

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?

@drbyte
Copy link
Collaborator

drbyte commented Mar 1, 2025

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants