我有一个Category
资源,如下所示:
<?php
namespace DomainCategoryResources;
use IlluminateHttpRequest;
use IlluminateHttpResourcesJsonJsonResource;
class CategoriesResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param Request $request
* @return array
*/
public function toArray($request): array
{
return [
'id' => (string)$this->id,
'type' => 'categories',
'attributes' => [
'name' => $this->name,
'slug' => $this->slug,
'parent' => $this->parent,
'description' => $this->description,
'image' => $this->image,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
]
];
}
}
parent
是类别的父级的ID,它本身就是Category
。当我调用返回此资源的端点时,我得到:
{
"data": {
"id": "5",
"type": "categories",
"attributes": {
"name": "Paper",
"slug": "paper",
"parent": 1,
"description": "test",
"image": null,
"created_at": "2022-09-09T19:01:44.000000Z",
"updated_at": "2022-09-09T19:01:44.000000Z"
}
}
}
这正是我所期望的。但现在我认为返回嵌套关系会更好,所以我不想返回上面的内容:
{
"data": {
"id": "5",
"type": "categories",
"attributes": {
"name": "Paper",
"slug": "paper",
"parent": {
"id": "5",
"type": "categories",
"attributes": {
"name": "Parent Paper",
"slug": "parent-paper",
"parent": 0,
"description": "test 2",
"image": "test.png",
"created_at": "2022-09-09T19:01:44.000000Z",
"updated_at": "2022-09-09T19:01:44.000000Z"
},
"description": "test",
"image": null,
"created_at": "2022-09-09T19:01:44.000000Z",
"updated_at": "2022-09-09T19:01:44.000000Z"
}
}
}
所以我考虑在模型中添加关系:
<?php
namespace DomainCategoryModels;
use DomainProductModelsProduct;
use DomainSharedBaseModel;
use IlluminateDatabaseEloquentRelationsHasMany;
use IlluminateDatabaseEloquentRelationsHasOne;
use IlluminateSupportStr;
class Category extends BaseModel
{
protected $fillable = [
'name',
'parent',
'description',
'image',
];
public function parent() : BelongsTo
{
return $this->belongsTo(Category::class, 'parent');
}
}
然后更新resource
:中的parent
字段
public function toArray($request): array
{
return [
'id' => (string)$this->id,
'type' => 'categories',
'attributes' => [
'name' => $this->name,
'slug' => $this->slug,
'parent' => new CategoriesResource($this->parent),
'description' => $this->description,
'image' => $this->image,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
]
];
}
但这不起作用。我收到一个错误,上面写着:
尝试读取属性";id";在内部
此错误指向ID字段:
public function toArray($request): array
{
return [
'id' => (string)$this->id,
``
Furthermore, I don't want it to get into a loop, meaning that when displaying the `parent` info I don't want it to display the parent's parent and so on.
Is this possible?
我在这里看到了几个问题:
为什么在HasOne关系上使用CategoryResource::集合?
而且,该父级可能嵌套,从而产生N+1问题,您应该在可能的情况下使用resources条件句:https://laravel.com/docs/9.x/eloquent-resources#conditional-关系
编辑:因此,应用此操作将防止进一步加载Category::parent
关系:
public function toArray($request): array
{
return [
'id' => (string)$this->id,
'type' => 'categories',
'attributes' => [
'name' => $this->name,
'slug' => $this->slug,
'parent' => new CategoriesResource($this->whenLoaded('parent')),
'description' => $this->description,
'image' => $this->image,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
]
];
}