Tricks

Use SelectFilter on distant relationships

Nov 22, 2022
Hugh Messenger
Table builder

This trick allows you to filter a table on a "distant" belongsTo relationship. For example, my app has Daily Logs for pilots to enter logs for Fight Legs on for a given aircraft. So each Flight Leg belongs to a Daily Log, and the Daily Log belongs to an Aircraft. So the relationship from Flight Legs to Aircraft is dailyLog.aircraft.n_number (where n_number is the aircraft's tail number or "N Number").

When displaying the entire Flight Legs table (rather than as a relation manager on a Daily Logs resource), I need to filter by the aircraft type from the parent Daily Log.

// filter name can be anything you want
SelectFilter::make('aircraft')
->label('Aircraft')
->options(
function () {
// could be more discerning here, and select a distinct list of aircraft id's
// that actually appear in the Daily Logs, so we aren't presenting filter options
// which don't exist in the table, but in my case we know they are all used
return Aircraft::all()->pluck('n_number', 'id')->toArray();
}
)
->query(function (Builder $query, array $data) {
if (!empty($data['value']))
{
// if we have a value (the aircraft ID from our options() query), just query a nested
// set of whereHas() clauses to reach our target, in this case two deep
$query->whereHas(
'dailyLog',
fn (Builder $query) => $query->whereHas(
'aircraft',
fn (Builder $query) => $query->where('id', '=', (int) $data['value'])
)
);
}
})

No comments yet…