laravel - 解析 api 资源中的 n+1
问题描述
我写这个问题是因为我找不到获得预期结果的方法。
我有 3 个模型:
1- User
2- Role
3- Permission
- 一个用户可以关联多个角色,因此用户和角色之间存在多对多的关系。
- 一个用户可以有多个直接关联的权限,所以用户和权限之间是多对多的关系。
- 一个角色可以有多个与之关联的权限,因此角色和权限之间存在多对多的关系。
我有 3 个具有以下结构的 api 资源:
1- UserResource
2- RoleResource
3- PermissionResource
应用程序/Http/Resources/UserResource.php
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class UserResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'roles' => RoleResource::collection($this->whenLoaded('roles')),
'permissions' => PermissionResource::collection($this->whenLoaded('permissions', $this->getInheritPermissions())),
];
}
}
应用程序/Http/Resources/UserResource.php
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class RoleResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'guard' => $this->guard,
'description' => $this->description,
'permissions' => PermissionResource::collection($this->whenLoaded('permissions'))
];
}
}
应用程序/Http/Resources/PermissionResource.php
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class PermissionResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'roles' => RoleResource::collection($this->whenLoaded('roles'))
];
}
}
在我的控制器中,我试图UserResource
用某个用户的数据返回资源,如下所示:
<?php
namespace App\Http\Controllers;
use App\Http\Resources\UserResource;
use App\Models\User;
class HomeController extends Controller
{
public function index()
{
return UserResource::collection(User::with(['roles', 'permissions'])->get());
}
}
我得到以下回应:
如果您查看roles
密钥,则permissions
关系也已加载,这是我不想要的,因为在控制器中我只加载roles
和permissions
关系。如果控制器按如下方式加载关系,这个答案会很好:
public function index()
{
return UserResource::collection(User::with(['roles.permissions', 'permissions'])->get());
}
好吧,我想这个问题已经给出,因为在User
模型中,我有一个名为 的方法getInheritPermissions()
,它获取用户从与其关联的角色继承的所有权限。
public function getInheritPermissions()
{
return $this->loadMissing('roles.permissions')->getAttribute('roles')->flatMap(function ($role) {
return $role->permissions;
});
}
这样,只获取用户拥有的角色权限的查询是非常高效的。但是在 API 资源中,它并没有像我预期的那样显示结果。我还了解到,在资源 API 中,我无法验证是否加载了嵌套关系。就像是:
'permissions' => PermissionResource::collection($this->whenLoaded('roles.permissions'))
我该如何控制这种情况,因为我需要使用 loadMissing 方法来加载用户从他们的角色中获得的权限。
非常感谢您提前。
解决方案
推荐阅读
- javascript - 如果隐藏了引导模式,如何在 jquery 中使函数为假?
- python-3.x - 在python中循环使用任何数字的文件名
- android - unity 覆盖 Android Application onCreate 方法
- php - Monolog 不记录 Symfony API 平台中的条目
- spring-webflux - Spring WebFlux 如何获取 Flux 执行结果?
- c++ - OpenCV cv::imshow() GUI 未显示
- javascript - 有没有办法在其动作或突变中获取 nameSpaced vuex 模块的名称?
- dart - 如何使用手势检测器以及如何创建可拖动的顶栏
- c++ - 从 Visual Studio 2017 中构建的依赖项中排除头文件
- angular - 翻译管道不能在 Material datepicker 自定义标题上无缝工作