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?
Advertisement
Answer
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')),