I've got a Category
resource that looks like this:
<?php
namespace Domain\Category\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
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
is the ID of the category's parent, which is itself a Category
. When I call the endpoint that returns this resource I get:
{
"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"
}
}
}
which is what I would expect. But now I'm thinking that it would be better to return the nested relationship, so instead of returning the above I'd like to return:
{
"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"
}
}
}
so I thought about adding the relationship to itself in the model:
<?php
namespace Domain\Category\Models;
use Domain\Product\Models\Product;
use Domain\Shared\BaseModel;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Support\Str;
class Category extends BaseModel
{
protected $fillable = [
'name',
'parent',
'description',
'image',
];
public function parent() : BelongsTo
{
return $this->belongsTo(Category::class, 'parent');
}
}
and then updating the parent
field in the resource
:
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,
]
];
}
but this is not working. I'm getting an error that says:
Attempt to read property "id" on int
This error is pointing to the ID field:
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?