Skip to content
Advertisement

laravel relationship not loading

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')),
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement