fix: Nested relationship sorting (#18058)

This commit is contained in:
Dan Harrin
2025-10-03 20:59:35 +01:00
committed by GitHub
parent 97220575e3
commit cad4abecb0
2 changed files with 14 additions and 68 deletions
@@ -5,7 +5,6 @@ namespace Filament\Tables\Columns\Concerns;
use Illuminate\Database\Connection;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Arr;
use function Filament\Support\generate_search_column_expression;
@@ -119,43 +118,20 @@ trait InteractsWithTableQuery
return $query;
}
$relationshipName = $this->getRelationshipName($query->getModel());
foreach (array_reverse($this->getSortColumns($query->getModel())) as $sortColumn) {
$query->orderBy($this->getSortColumnForQuery($query, $sortColumn), $direction);
$sortColumn = (string) str($sortColumn)->replace('.', '->');
if ($relationshipName) {
$query->orderByPowerJoins("{$relationshipName}.{$sortColumn}", $direction); /** @phpstan-ignore method.notFound */
continue;
}
$query->orderBy($sortColumn, $direction);
}
return $query;
}
/**
* @param array<string> | null $relationships
*/
protected function getSortColumnForQuery(EloquentBuilder $query, string $sortColumn, ?array $relationships = null): string | Builder
{
$relationships ??= ($relationshipName = $this->getRelationshipName($query->getModel())) ?
explode('.', $relationshipName) :
[];
if (! count($relationships)) {
return (string) str($sortColumn)->replace('.', '->');
}
$currentRelationshipName = array_shift($relationships);
$relationship = $this->getRelationship($query->getModel(), $currentRelationshipName);
$relatedQuery = $relationship->getRelated()::query();
return $relationship
->getRelationExistenceQuery(
$relatedQuery,
$query,
[$currentRelationshipName => $this->getSortColumnForQuery(
$relatedQuery,
$sortColumn,
$relationships,
)],
)
->applyScopes()
->getQuery();
}
}
+3 -33
View File
@@ -321,41 +321,11 @@ class Group extends Component
]) ?? $query;
}
return $query->orderBy($this->getSortColumnForQuery($query, $this->getRelationshipAttribute()), $direction);
}
/**
* @param array<string> | null $relationships
*/
protected function getSortColumnForQuery(EloquentBuilder $query, string $sortColumn, ?array $relationships = null, ?Relation $lastRelationship = null): string | Builder
{
$relationships ??= ($relationshipName = $this->getRelationshipName()) ?
explode('.', $relationshipName) :
[];
if (! count($relationships)) {
return $lastRelationship ? $lastRelationship->getQuery()->getModel()->qualifyColumn($sortColumn) : $sortColumn;
if ($relationshipName = $this->getRelationshipName()) {
return $query->orderByPowerJoins("{$relationshipName}.{$this->getRelationshipAttribute()}", $direction); /** @phpstan-ignore method.notFound */
}
$currentRelationshipName = array_shift($relationships);
$relationship = $this->getRelationship($query->getModel(), $currentRelationshipName);
$relatedQuery = $relationship->getRelated()::query();
return $relationship
->getRelationExistenceQuery(
$relatedQuery,
$query,
[$currentRelationshipName => $this->getSortColumnForQuery(
$relatedQuery,
$sortColumn,
$relationships,
$relationship,
)],
)
->applyScopes()
->getQuery();
return $query->orderBy($this->getRelationshipAttribute(), $direction);
}
public function scopeQuery(EloquentBuilder $query, Model $record): EloquentBuilder