Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Synchro's avatar

Nova relatable filter with two-part name

I was very happy to find this post as it discusses exactly what I wanted to do, however, I can't make it work. I have a BelongsTo field defined like this:

BelongsTo::make('Logistics Provider', 'logistics', Customer::class)
    ->nullable()
    ->sortable();

"logistics providers" are a subset of my Customers. The model this is a resource for has a belongsTo relation called logistics which links to the Customer model, and applies a filter in there, however, that filter doesn't seem to be used, so I need to use a Nova relatable to filter it instead. I defined it like this:

public static function relatableLogistics(NovaRequest $request, $query)
{
    return $query->where('type', \App\Models\Customer::TYPE_LOGISTICS);
}

but that doesn't trigger (if I stick a dd in it, everything stays working, and the list of related Customers is not filtered), so I tried naming it relatableLogisticsProviders and relatableCustomers, but they didn't trigger either. What should I name this relatable to make it match that field?

0 likes
3 replies
Synchro's avatar

Aha - Seems like I didn't check my last attempt correctly. Naming it relatableCustomers does work. It's cool that it works, but this approach will be problematic where I have multiple fields related to the same resource type that do not all require this filtering. Is there some way to make it match on the field name/title rather than the target resource name?

Synchro's avatar

In the Nova docs it says this:

When a Nova resource depends on another resource via multiple fields, you will often assign the fields different names. In these situations, you should supply a third argument when defining the relationship to specify which Nova resource the relationship should utilize, since Nova may not be able to determine this via convention:

HasMany::make('Owned Teams', 'ownedTeams', Team::class),
BelongsToMany::make('Teams', 'teams', Team::class)

However, I don't see how this can work because both relations will use the same relatableTeams method. For this example, imagine that there is perhaps a "can own teams" field that would distinguish the two relations, and you would want relatableTeams to return different results for each case.

Synchro's avatar
Synchro
OP
Best Answer
Level 2

OK, I figured this out! You can pass in a Field property and then inspect its name, and do different things accordingly. In one of my cases:

public static function relatableLocations(NovaRequest $request, $query, Field $field)
{
    if ($field->attribute === 'depot') {
        return $query->where('type', \App\Models\Location::TYPE_DEPOT);
    }
    return $query;
}

Please or to participate in this conversation.