Skip to content

Using Scout, relationship search on HasMany field returns results from all resources, not scoped to certain resource #6622

@ekateiva

Description

@ekateiva
  • Laravel Version: 11.30.0
  • Nova Version: v4.35.4 (Silver Surfer)
  • PHP Version: 8.3.9
  • Database Driver & Version: MySQL 8 + Scout (Algolia)
  • Operating System and Version: MacOs
  • Browser type and version: Chrome (130.0.6723.92)
  • Reproduction Repository: https://github.com/ekateiva/laravel_nova_issue_6622/

Description:

When using a HasMany relationship between resources (e.g., Supplier and Product where a Supplier has many Products), searching through the related resource from the parent resource's page does not properly scope the results.
E.g. In certain supplier page (/nova/resources/suppliers/60) I search for Product with query test, and the results come from all supplier, not the one with ID 60. Product resource has Scout enabled.

Detailed steps to reproduce the issue on a fresh Nova installation:

  1. Define a Supplier resource with a HasMany relationship to Product:
public function fields(Request $request)
{
    return [
        HasMany::make('Products'),
    ];
}
  1. Use Laravel Scout for searching in the Product resource.
public static function usesScout(): bool
{
    return true;
}
  1. Navigate to a specific Supplier page in Laravel Nova.
  2. Use the search functionality in the Products relationship field.
  3. Observe that the search results include Products from all Suppliers, not just the current Supplier.

Workaround

As a workaround, this code can be used in Product resource:

public static function scoutQuery(NovaRequest $request, $query): \Laravel\Scout\Builder
{
    return $query
        ->when(
            $request->viaResource() && $request->viaResourceId,
            function (\Laravel\Scout\Builder $query) use ($request) {
                $algoliaIndexedField = match ($request->viaResource) {
                    Supplier::uriKey() => 'supplier_id',
                    default => null,
                };

                if (! $algoliaIndexedField) {
                    \\ Log...

                    return $query;
                }

                return $query->where($algoliaIndexedField, $request->viaResourceId);
            },
        );
}

In Laravel Nova documentation you can find this:

For this reason, Nova integrates seamlessly with Laravel Scout. When the Laravel\Scout\Searchable trait is attached to a model associated with a Nova resource, Nova will automatically begin using Scout when performing searches against that resource. There is no other configuration required.

So it's not totally true, if the search does not scope the results via relationships :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugVerified bug by the Nova teamfix incomingA fix is in review

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions