SelectFilter by 2 level relationship

I want to make a SelectFilter by country in a table where I show vehicles. The data model is as follows: Vehicle - id - name - place_id Place - id - name - country_id Country - id - code - name That is, a Vehicle belongs to a Place and a Place has a Country. My current code is as follows, the filter shows it but the changes are not applied:
SelectFilter::make('place.country.code')
->label(__('Country'))
->options(fn () => Country::pluck('name', 'code')->toArray())
->multiple()
->searchable()
->preload(),
SelectFilter::make('place.country.code')
->label(__('Country'))
->options(fn () => Country::pluck('name', 'code')->toArray())
->multiple()
->searchable()
->preload(),
Thanks
Solution:
Filament
Use SelectFilter on distant relationships by Hugh Messenger - Trick...
Filament is a collection of tools for rapidly building beautiful TALL stack apps, designed for humans.
Jump to solution
15 Replies
abdullafahem
abdullafahem6mo ago
I think your problem is with SelectFilter::make('place.country.code') the name of SelectFilter I don't think should be named like this can you try only for example country and show some results?
Roberto S.
Roberto S.OP6mo ago
I get a SQL error:
SELECT
count(*) AS aggregate
FROM
"vehicles"
WHERE
"status" = PUB
AND ("country" IN (CN))
SELECT
count(*) AS aggregate
FROM
"vehicles"
WHERE
"status" = PUB
AND ("country" IN (CN))
`
abdullafahem
abdullafahem6mo ago
Did you have declare functions in your models for relationships?
Roberto S.
Roberto S.OP6mo ago
Yes, I do: Vehicle.php
public function place(): BelongsTo
{
return $this->belongsTo(Place::class);
}
public function place(): BelongsTo
{
return $this->belongsTo(Place::class);
}
Place.php
public function country(): BelongsTo
{
return $this->belongsTo(Country::class);
}

public function vehicles(): HasMany
{
return $this->hasMany(Vehicle::class);
}
public function country(): BelongsTo
{
return $this->belongsTo(Country::class);
}

public function vehicles(): HasMany
{
return $this->hasMany(Vehicle::class);
}
Country.php
public function place(): HasMany
{
return $this->hasMany(Place::class);
}
public function place(): HasMany
{
return $this->hasMany(Place::class);
}
abdullafahem
abdullafahem6mo ago
Can you remove the .code just let it place.country Because I think the code should came from the options And this SelectFilter you are implement it in VehicleResource?
Roberto S.
Roberto S.OP6mo ago
The result is the same, the filter is shown but doesn't do nothing 😦
No description
abdullafahem
abdullafahem6mo ago
The countries how did you save in the DB And please try to remove the multiple for just once
Roberto S.
Roberto S.OP6mo ago
No description
Roberto S.
Roberto S.OP6mo ago
The result without
multiple()
multiple()
is the same
abdullafahem
abdullafahem6mo ago
SelectFilter::make('code') ->label(__('Country')) ->relationship(place.country.code', 'name') Can you try like this? SelectFilter::make('place.country.code') ->label(__('Country')) ->options(fn () => Country::pluck('code', 'id')->toArray()) Or like this
Roberto S.
Roberto S.OP6mo ago
This one throws an error: Filament\Support\Services\RelationshipJoiner::prepareQueryForNoConstraints(): Argument #1 ($relationship) must be of type Illuminate\Database\Eloquent\Relations\Relation, null given, called in /Users/rsv/Herd/my_project/vendor/filament/forms/src/Components/Select.php on line 763
Roberto S.
Roberto S.OP6mo ago
This one doesn't work too 😦
No description
Solution
abdullafahem
abdullafahem6mo ago
Filament
Use SelectFilter on distant relationships by Hugh Messenger - Trick...
Filament is a collection of tools for rapidly building beautiful TALL stack apps, designed for humans.
abdullafahem
abdullafahem6mo ago
I think is usefull
Roberto S.
Roberto S.OP6mo ago
Thank you very much for your help! It's working now! This is the code:
SelectFilter::make('country')
->label(__('Country'))
->options(fn () => Country::pluck('name', 'code')->toArray())
->query(function (Builder $query, array $data) {
if (! empty($data['value'])) {
$query->whereHas(
'place',
fn (Builder $query) => $query->whereHas(
'country',
fn (Builder $query) => $query->where('code', '=', $data['value'])
)

);
}
}),
SelectFilter::make('country')
->label(__('Country'))
->options(fn () => Country::pluck('name', 'code')->toArray())
->query(function (Builder $query, array $data) {
if (! empty($data['value'])) {
$query->whereHas(
'place',
fn (Builder $query) => $query->whereHas(
'country',
fn (Builder $query) => $query->where('code', '=', $data['value'])
)

);
}
}),
Want results from more Discord servers?
Add your server