Reputation: 1681
I have two models Sale and Shipment with following relation in Sale.
/**
* @return BelongsTo
*/
public function shipment() : BelongsTo
{
return $this->belongsTo( Shipment::class);
}
When sending sale resources via controller .. I have the following SaleResource::toArray method
public function toArray($request)
{
return [
'shipment' => ShipmentResource::make($this->shipment),
/** see comments in question */
// 'shipment' => $this->shipment,
];
}
Shipment object has many attached models , like address, group etc. It has a resource defined with it overridden toArray method
public function toArray($request) {
$shipment = [
'tracking' => $this->tracking
];
if ($request->routeIs('get-picked')) {
$shipment['destination] = AddressResource::make($this->address)
}
return $shipment;
}
We are fetching Sale using with
to avoid n+1 issues.
/** @var Builder $query */
$query = Sale::query()->with([
'shipment','shipment.ship_service',
'inventory', 'inventory.book',
'destination' ,
'owner'
]);
However when we use ShipmentResource::make($shipment) , it looks like laravel 8 is provides the resource a shipment object that fetches all related objects again using lazy loading causing n+1 queries.
Notice when we use the commented line, // 'shipment' => $this->shipment,
n+1 issue is completely avoided but laravel does not use ShipmentResource::toArray() method at all .. and instead returns a shipment object without custom fields destination
that are added in ShipmentResource::toArray .
That is a problem because we need the field destination
in front end. Those fields are handled as custom since these are not needed in all requests and we selectively use those based on what route was called.
Any help or pointers in this regard are greatly appreciated. Please let me know if the question requires any further clarification.
Upvotes: 0
Views: 17