Order a Filament table by a date column with NULL values first

The custom CMS I am using for this blog uses Laravel and Filament under the hood. The data model is rudimentary - I currently have separate models for the blog posts and entries for the 365 Albums project, each of which have a published_at column. This is used to control visibility on the site - it allows me to schedule posts in the future, as well as create ‘draft’ posts with no published_at value (i.e. NULL).

On the Filament tables that power the UI in the backend, I want to list the posts (or albums) in reverse chronological order, with the newest (and future scheduled) posts first. I also want to show draft posts first.

In MySQL, when using ascending order the NULL values come first - so by flipping this (i.e. using DESC order) the NULL values come last.

One way we can get around this my using a minus operator on the column name:

ORDER BY -published_at ASC

This will reverse all of the date values (essentially ordering by DESC), without affecting the NULL values on the column. This will keep them before the values with a date when sorting in ascending order.

On the Filament resource we can add a default sort order to the return value of the table static method:

->defaultSort(fn ($query) => $query->orderByRaw('-published_at asc'));

This is just one way to achieve this sorting behaviour. I may change this up in the future (when I have more database entries) to see if there is an optimal approach.

It’s worth noting that PostgreSQL treats NULL values as very large, so will automatically put the ‘draft’ posts before the dated posts when sorting in descending order.

Reply via email