Unexpected NULL rows and sort direction loss when sorting FilamentPHP table columns by relationship attributes
0 reputation · 22 Jun 2022, 13:38 UTC
0 reputation · 22 Jun 2022, 13:38 UTC
When configuring a FilamentPHP table column to sort by a related model attribute using $table->column('user.name', 'User Name')->sortable(), the goal is to understand if the generated query includes the necessary join for the relationship and how rows with null foreign keys are ordered.
Uncertainty remains about whether the join is added automatically in Filament 3.2+ or must be declared manually, and whether the sort direction stored in the URL persists after a page reload when the relationship column is used.
Does enabling sortable() on a BelongsTo column automatically add a LEFT JOIN in Filament 3.2+, or must I manually join the relationship? How does the presence of NULL foreign keys affect the order of rows when sorting ascending versus descending? Does the sortDirection URL parameter persist after a page reload when sorting by a relationship column?
34275 reputation · 22 Jun 2022, 23:21 UTC
With Filament 3.2+ and a column defined as $table->column('user.name', 'User Name')->sortable(), Filament adds the join for you. You do not need to manually join the relationship for sorting to work.
Sort direction is stored in the URL as ?sort=user.name&sort_direction=asc|desc for any sortable column, including relationship columns. It persists after a page reload as long as the column definition is unchanged and the table query is not overridden in a way that removes the join.
->sortable() on a dot-notation column causes Filament to add a LEFT JOIN to the related table automatically.modifyQueryUsing() or add constraints that change the join to INNER JOIN, rows with NULL foreign keys are filtered out and the apparent sort direction can seem lost.DB::listen(function ($query) { logger()->info($query->sql, $query->bindings); });Look for a LEFT JOIN on the related table when sort=user.name is in the request.
sort and sort_direction remain in the URL and the order is unchanged.$table->column('user.name')->sortable()->nullsLast();Use nullsFirst() or nullsLast() to make placement deterministic across databases.
One diagnostic detail that changes the recommendation: which database engine you are using and whether modifyQueryUsing() is applied to the table query. NULL ordering defaults differ by DB, and a custom query can replace Filament’s LEFT JOIN.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.