Получите один результат сбора из 2 глубоких отношений «многие ко многим»

#eloquent #nested #many-to-many #laravel-8 #laravel-collection

Вопрос:

Название немного сбивает с толку. Роли-это отношения «многие ко многим» от пользователя, а разрешения-отношения ролей «многие ко многим». Но я хочу получить все разрешения для ролей, которые есть у пользователя. Теперь у меня есть этот код для этого, но я подумал, может быть, есть лучший способ?

 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;
    });
}
 

Что я здесь делаю, так это: я перебираю роли пользователя. Затем получите разрешения роли, зациклившись на разрешениях, а затем проверьте, есть ли у пользователя разрешение *. Если это так, то оно возвращает значение true. В противном случае перейдите к функции getFilteredArray, чтобы отфильтровать массив разрешений, переданный этому методу. И если этот результат больше 0, то верните true, в противном случае false. Но я думаю, что для этого есть гораздо лучшее решение.

Ответ №1:

в этом коде проверьте, есть ли у пользователя роли, выполните цикл сбора ролей и соберите связанные с ними разрешения. Верните коллекцию разрешений, в противном случае значение 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;
 

Комментарии:

1. Извините за поздний ответ, я был очень занят, но спасибо за это решение. Я еще не тестировал его, но скоро сделаю это!