I've got a Product
and a Category
models:
class Product extends BaseModel
{
use Uuid;
protected $fillable = [
'barcode',
'name',
'sku',
'description',
'type',
'category_id',
'wholesale_price',
'retail_price',
'base_picture',
'current_stock_level',
'active',
];
public function category(): BelongsTo
{
return $this->belongsTo(Category::class, 'category_id');
}
class Category extends BaseModel
{
protected $fillable = [
'name',
'parent',
'description',
'image',
];
public function product(): HasMany
{
return $this->hasMany(Product::class, 'category_id');
}
In my controller, I'm retrieveing all products and wanted to return the category object the product belongs to in the response, so I'm doing:
class ProductsController extends Controller
{
public function index(): AnonymousResourceCollection
{
$products = Product::all();
return ProductsResource::collection($products->loadMissing('category'));
}
and my resource looks like:
class ProductsResource extends JsonResource
{
public function toArray($request) : array
{
return [
'id' => $this->id,
'type' => 'products',
'attributes' => [
'barcode' => $this->barcode,
'name' => $this->name,
'slug' => $this->slug,
'sku' => $this->sku,
'description' => $this->description,
'type' => $this->type,
// todo return category object?
'category' => new CategoriesResource($this->whenLoaded('category_id')),
'wholesale_price' => $this->wholesale_price,
'retail_price' => $this->retail_price,
'base_picture' => $this->base_picture,
'current_stock_level' => $this->current_stock_level,
'active' => $this->active,
]
];
}
}
but the response I'm getting is:
{
"data": [
{
"id": "a2102c4c-c14a-4d16-af28-e218bcc4fe39",
"type": "products",
"attributes": {
"barcode": "1010101010101",
"name": "phione",
"slug": "phione",
"sku": "w2e2r2",
"description": null,
"type": "services",
"wholesale_price": 54,
"retail_price": 34,
"base_picture": null,
"current_stock_level": 0,
"active": 1
}
}
]
}
I tried loading the relationship differently:
public function index(): AnonymousResourceCollection
{
$products = Product::with('category')->get();
return ProductsResource::collection($products);
}
but the result is the same.
It seems that the relationship is well established because if I run:
$product = Product::first();
dd($product->category);
I can see the category the product belongs to:
#attributes: array:8 [▼
"id" => 2
"name" => "Paper"
"slug" => "paper"
"parent" => 1
"description" => null
"image" => null
"created_at" => "2022-09-20 02:03:05"
"updated_at" => "2022-09-20 02:03:05"
]
what am I missing?
CodePudding user response:
In controller load category
relation with eager loading
$products = Product::with('category');
return ProductsResource::collection($products);
and in the ProductsResource file load, the relation category
, not category_id
'category' => CategoriesResource::collection($this->whenLoaded('category')),
CodePudding user response:
You don't need to use a collection here. Simply do
$products = Product::with('category')->get();
return response()->json($products);