laravel / nova-issues

554 stars 35 forks source link

BelongsToMany runs excessive (heavy) queries #6451

Open fruitl00p opened 2 months ago

fruitl00p commented 2 months ago

Description:

We have a BelongsToMany relation which seems to do a lot of queries eventhough the original pivot is empty?

We have the following setup:

Model: Compontent

    public function cook_products(): BelongsToMany
    {
        return $this->belongsToMany(Product::class)
            ->wherePivot('direction', ComponentProductDirection::ToProduct)
            ->withPivot(['direction', 'quantity']);
    }

And in Nova we have:

            BelongsToMany::make(__('Cook products'), 'cook_products', Product::class)
                ->searchable()
                ->fields(fn () => [
                    Number::make(__('Quantity'), 'quantity')
                        ->readonly(!$request->user()->isAdmin())
                        ->rules('required'),
                    Hidden::make('direction')
                        ->default(ComponentProductDirection::ToProduct),
                ]),

When hitting the details page this incurs a /nova-api/products?search request with the following filter (shortened):

[
  "search" => ""
  "filters" => "<some hash, removed for brevity>"
  "orderBy" => ""
  "perPage" => "5"
  "trashed" => ""
  "page" => "1"
  "viaResource" => "components"
  "viaResourceId" => "25"
  "viaRelationship" => "cook_products"
  "relationshipType" => "belongsToMany"
]

This results in 14 queries of which 10 are duplicate?

image

(even though there were no relations)

If having 9 actual cook_products relations this balloons to 67 queries of which 7 where unique (!)

I'm not sure if this is a bug, a feature request or missing documentation. (or something else)

fruitl00p commented 2 months ago

Further inspection reveals that in the XHR request for /nova-api/ I can't alter the construction of the 'component' class to exclude all other relations (i.e. using a without() call in the nova-api/-request. Also It seems that this is where the issue stems from; both Component and 'Product' and the Pivot have even more releations that are N+1 Queried multiple times... Hence the massive increase in (duplicate) queries.

Any way I can hook into this (without sacrificing the '$with = []' in my models?

crynobone commented 2 months ago

Please provide full reproducing repository based on fresh installation as suggested in the bug report template (or you can refer to https://github.com/nova-issues for example)