Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

anjama's avatar

Cleanly query role in RBAC from set of permissions using eloquent?

Given a Role-Based Access Control (RBAC) design (see figure), I'm wondering if there is a clean way to query for the existence of a role (parent table) that exactly matches a specific set of role permissions (child table)? I can certainly do it using a combination of eloquent and application logic in PHP, but I'm curious if there is a clean way to do it with just Eloquent if I already have an array of permission IDs (permission_id in the figure). Performance is not an issue (will very rarely be used).

RBAC

0 likes
3 replies
anjama's avatar

@jlrdw Thank you, that video will definitely be helpful for some of the things I need to do eventually. I'll keep an eye out for that other video you mentioned and post it if I find it.

I did find Spatie's laravel-permission package which has a hasExactRoles method that is giving me some inspiration.

Alternatively, when creating roles, I might just take the permission names or ids and generate a unique key from them and store it in the role table. Then in the future, I can just lookup roles by converting a permission list into a key and just searching for that.

anjama's avatar

Posting my current solution that seems to work. Will take an array of Permission ids and either find or create a Role that matches that set of ids exactly.

$role = Role::whereIn('id',
            RolePermission::select('role_id')
                ->groupBy('role_id')
                ->havingRaw('COUNT(*) = ?', [count($ids)])
        )
        ->whereIn('id',
            RolePermission::select('role_id')
                ->whereIn('permission_id', $ids)
                ->groupBy('role_id')
                ->havingRaw('COUNT(*) = ?', [count($ids)])
        )
        ->firstOr(function() use ($ids) {
            $role = Role::create();
            $role->permissions()->attach($ids);
            return $role;
        });
1 like

Please or to participate in this conversation.