Scalable
Scalable

Reputation: 1681

Laravel 8 Resource::make causing N+1 Queries problem

Background

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;
  }

The Problem

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 destinationthat 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

Answers (0)

Related Questions