Search code examples
eloquentnestedmany-to-manylaravel-8laravel-collection

Get one collection result from 2 deep many-to-many relationship


The title is a little bit confusing. Roles are a many-to-many relationship from user and permissions a many-to-many relationship of roles. But I want to get all the permissions of the roles that the user has. Now I have this code for doing that, but I thought maybe there is a better way?

public function hasPermissions(array $permissions = []): bool
{
    $this->loadMissing('roles');

    foreach ($this->roles as $role) {
        foreach ($role->permissions as $permission) {
            if (count($this->getFilteredArray($permissions, 
                $permission['permission'])) > 0) {
                return true;
            }
            dd('hier 2');
        }
    }
    return false;
}

private function getFilteredArray($arrayToFilter, $valueToCheck): array
{
    return array_filter($arrayToFilter, function ($value) use ($valueToCheck) {
        return $valueToCheck === $value;
    });
}

What I'm doing here is: I for-loop over the roles of the user. Then get the role's permissions, for-loop over the permissions, and then check if a user has permission *. If it has, it returns true. Otherwise, go to function getFilteredArray to filter the permissions array that was passed to this method. And if that result is bigger than 0, then return true otherwise false. But I think there is a much better solution for this.


Solution

  • this code, check if the user have roles, loop roles collection and collect the permission related with them. Return the permission collection, otherwise null

    $roles = auth()->user()->roles()->exists() ? auth()->user()->roles()->pluck('id') : null;
    if($roles) {
      $collection = Role::whereIn('id', $roles)->get();
      $collectPermission = collect();
      foreach($collection as $role) {
         if($role->permissions()->exists()) {
            $role->permissions()->filter(function ($permission) use ($collectPermission) {
             $collectPermission->push($permission);
            });
         }
      }
      return $collectPermission;
    }
    return null;