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

SNaRe's avatar
Level 7

Filtering: Displaying Records with Relationships in Another Table

I'm trying to create a list of event instances and want to filter them based on the country where the events will take place with Filamentphp.

I have three tables: event_instances, events, and countries.

  • Each event_instance belongs to one event.
  • Each event can have multiple event instances.
  • Each event belongs to one country.
  • Each country can have multiple events.
  • I have a country_id column in the events table.

I have these relationships

class Event extends Model
{
    public function country()
    {
        return $this->belongsTo(Country::class);
    }
}
class Country extends Model
{
    public function events()
    {
        return $this->hasMany(Event::class);
    }
}
class EventInstance extends Model
{
    public function event()
    {
        return $this->belongsTo(Event::class);
    }
}
class Event extends Model
{
    public function eventInstances()
    {
        return $this->hasMany(EventInstance::class);
    }

    public function country()
    {
        return $this->belongsTo(Country::class);
    }
}

When I do this to verify if relations are successfully working.

$eventInstance = EventInstance::find($id);
$country = $eventInstance->event->country;

It also gives me this

App\Models\Country {#6998
    id: 2,
    name: "Aland Islands",
  }

I want to filter the dropdown menu of countries to only show the countries where events will take place. But it shows all countries in the countries table.

SelectFilter::make('country')
    ->label('Country')
    ->relationship('event.country', 'name')

What I am missing here?

0 likes
3 replies
LaryAI's avatar
Level 58

It seems like you want to filter the dropdown menu to only show countries that have associated events. To achieve this, you need to modify the query used to populate the dropdown menu so that it only includes countries with at least one event.

Here's how you can adjust your SelectFilter to achieve this:

SelectFilter::make('country')
    ->label('Country')
    ->options(function () {
        // Get all countries that have at least one event
        return Country::has('events')->get()->pluck('name', 'id');
    });

In this code snippet, the options method is used to provide a closure that returns the list of countries with their names and IDs. The has('events') method is used to filter the countries to only include those that have associated events.

This should ensure that your dropdown only shows countries where events will take place.

synsyst's avatar

Hey SNaRe

Did you ever find a solution? I have the same issue. relationship shows all entries, also duplicates in case the same value appears several times, such as a category type value - I'd think something like this would assume that we'd want to have unique values and only values that are present in the current set of the table selection.

Please or to participate in this conversation.