You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When a resource has a fieldsForIndex method, and defines a field using the same attribute as another field in the fields method, where the field defined in fieldsForIndex is marked as filterable, and the other field using the same attribute isn't, Nova is unable to find the filterable field.
This happens because in ResolvesFields@filterableFields, Nova is grabbing all fields in the fields, fieldsForIndex, and fieldsForDetail method, and then applying a unique collection filter on the fields. If there's two fields with the same attribute, the unique filter arbitrary picks the first one, rather than the one that is marked as filterable.
It's worth noting that the ResolvesFields@filterableFields method does call the withOnlyFilterableFields filter, but this filter reduces the collection to fields that have the potential to be filterable, not fields that are actually marked as filterable. Once things bubble up into ResolvesFilters@resolveFiltersFromFields, and $field->resolveFilter($request) is called, which is where fields that truly are marked as filterable get filtered.
Suggestion Solution:
In ResolvesFields@filterableFields, before the unique filter, you could first sort the fields by whether or not they are marked as filterable. This would guarantee that if there are duplicate fields (by attribute), the field that's marked as filterable will get picked first.
Alternatively, in ResolvesFields@buildAvailableFields, you could grab from the fields defined by the $methods parameter first, and push in the fields defined in the fields method last.
Detailed steps to reproduce the issue on a fresh Nova installation:
In short, this results in "no filterable fields", despite the resource reading as, "the title field is filterable".
To break this down, ResolvesFields@availableFieldsOnIndexOrDetail pulls in fields first, then fieldsForIndex. This means that the non-filterable field comes first in the collection. Then in ResolvesFields@filterableFields, both fields will pass the withOnlyFilterableFields collection filter, has both fields have the potential to be filterable, even though only one of them actually has a filter callback. The unique collection filter right after that then drops the second field (which came from fieldsForIndex, and was actually marked as filterable). Once this bubbles up to ResolvesFilters@resolveFiltersFromFields, the method will return an empty collection.
Other Arrangements
It's worth noting that if the same field is defined in fieldsForIndex and fieldsForDetail, this issue doesn't happen. However, in a lot of cases, I define my index fields separately from my general fields, as they tend to be different enough (or ordered differently) that it's easier to just define it in a separate method.
The text was updated successfully, but these errors were encountered:
tylernathanreed
changed the title
Filterable fields don't resolve correctly when both Index and Detail variants exist
Filterable fields don't resolve correctly when both Index and General variants exist
Jun 12, 2024
Description:
When a resource has a
fieldsForIndex
method, and defines a field using the same attribute as another field in thefields
method, where the field defined infieldsForIndex
is marked asfilterable
, and the other field using the same attribute isn't, Nova is unable to find the filterable field.This happens because in
ResolvesFields@filterableFields
, Nova is grabbing all fields in thefields
,fieldsForIndex
, andfieldsForDetail
method, and then applying aunique
collection filter on the fields. If there's two fields with the same attribute, theunique
filter arbitrary picks the first one, rather than the one that is marked asfilterable
.It's worth noting that the
ResolvesFields@filterableFields
method does call thewithOnlyFilterableFields
filter, but this filter reduces the collection to fields that have the potential to be filterable, not fields that are actually marked asfilterable
. Once things bubble up intoResolvesFilters@resolveFiltersFromFields
, and$field->resolveFilter($request)
is called, which is where fields that truly are marked asfilterable
get filtered.Suggestion Solution:
In
ResolvesFields@filterableFields
, before theunique
filter, you could first sort the fields by whether or not they are marked asfilterable
. This would guarantee that if there are duplicate fields (by attribute), the field that's marked asfilterable
will get picked first.Alternatively, in
ResolvesFields@buildAvailableFields
, you could grab from the fields defined by the$methods
parameter first, and push in the fields defined in thefields
method last.Detailed steps to reproduce the issue on a fresh Nova installation:
Here's an example:
In short, this results in "no filterable fields", despite the resource reading as, "the title field is filterable".
To break this down,
ResolvesFields@availableFieldsOnIndexOrDetail
pulls infields
first, thenfieldsForIndex
. This means that the non-filterable field comes first in the collection. Then inResolvesFields@filterableFields
, both fields will pass thewithOnlyFilterableFields
collection filter, has both fields have the potential to be filterable, even though only one of them actually has a filter callback. Theunique
collection filter right after that then drops the second field (which came fromfieldsForIndex
, and was actually marked asfilterable
). Once this bubbles up toResolvesFilters@resolveFiltersFromFields
, the method will return an empty collection.Other Arrangements
It's worth noting that if the same field is defined in
fieldsForIndex
andfieldsForDetail
, this issue doesn't happen. However, in a lot of cases, I define my index fields separately from my general fields, as they tend to be different enough (or ordered differently) that it's easier to just define it in a separate method.The text was updated successfully, but these errors were encountered: