mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 13:33:20 +12:00
fix: allow sorting on aggs, w/o loading
This commit is contained in:
parent
45fe33c3fc
commit
4b23dd179f
2 changed files with 52 additions and 18 deletions
|
@ -67,6 +67,9 @@ defmodule Ash.Actions.Sort do
|
|||
attribute = Ash.Resource.Info.attribute(resource, field)
|
||||
|
||||
cond do
|
||||
aggregate = Ash.Resource.Info.aggregate(resource, field) ->
|
||||
aggregate_sort(aggregates, aggregate, order, resource, sorts, errors)
|
||||
|
||||
Map.has_key?(aggregates, field) ->
|
||||
aggregate_sort(aggregates, field, order, resource, sorts, errors)
|
||||
|
||||
|
@ -94,7 +97,7 @@ defmodule Ash.Actions.Sort do
|
|||
end
|
||||
|
||||
!attribute ->
|
||||
{sorts, [NoSuchAttribute.exception(attribute: field) | errors]}
|
||||
{sorts, [NoSuchAttribute.exception(name: field) | errors]}
|
||||
|
||||
Ash.Type.embedded_type?(attribute.type) ->
|
||||
{sorts, ["Cannot sort on embedded types" | errors]}
|
||||
|
@ -141,16 +144,38 @@ defmodule Ash.Actions.Sort do
|
|||
end
|
||||
|
||||
defp aggregate_sort(aggregates, field, order, resource, sorts, errors) do
|
||||
{field, type} =
|
||||
case field do
|
||||
field when is_atom(field) ->
|
||||
aggregate = Map.get(aggregates, field)
|
||||
|
||||
{field, {:ok, aggregate.type}}
|
||||
|
||||
%Ash.Resource.Aggregate{} = agg ->
|
||||
field_type =
|
||||
if agg.field do
|
||||
related = Ash.Resource.Info.related(resource, agg.relationship_path)
|
||||
Ash.Resource.Info.attribute(related, agg.field).type
|
||||
end
|
||||
|
||||
{agg.name, Ash.Query.Aggregate.kind_to_type(agg.kind, field_type)}
|
||||
end
|
||||
|
||||
case type do
|
||||
{:ok, type} ->
|
||||
if Ash.DataLayer.data_layer_can?(resource, :aggregate_sort) &&
|
||||
Ash.DataLayer.data_layer_can?(
|
||||
resource,
|
||||
{:sort, Ash.Type.storage_type(aggregate.type)}
|
||||
{:sort, Ash.Type.storage_type(type)}
|
||||
) do
|
||||
{sorts ++ [{field, order}], errors}
|
||||
else
|
||||
{sorts, [AggregatesNotSupported.exception(resource: resource, feature: "sorting") | errors]}
|
||||
{sorts,
|
||||
[AggregatesNotSupported.exception(resource: resource, feature: "sorting") | errors]}
|
||||
end
|
||||
|
||||
{:error, error} ->
|
||||
{sorts, [error | errors]}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1541,6 +1541,7 @@ defmodule Ash.Query do
|
|||
query = to_query(query)
|
||||
|
||||
if Ash.DataLayer.data_layer_can?(query.resource, :sort) do
|
||||
query_with_sort =
|
||||
sorts
|
||||
|> List.wrap()
|
||||
|> Enum.reduce(query, fn
|
||||
|
@ -1551,6 +1552,14 @@ defmodule Ash.Query do
|
|||
%{query | sort: query.sort ++ [{sort, :asc}]}
|
||||
end)
|
||||
|> validate_sort()
|
||||
|
||||
Enum.reduce(query_with_sort.sort || [], query_with_sort, fn {key, _value}, query ->
|
||||
if Ash.Resource.Info.aggregate(query.resource, key) do
|
||||
Ash.Query.load(query, key)
|
||||
else
|
||||
query
|
||||
end
|
||||
end)
|
||||
else
|
||||
add_error(query, :sort, "Data layer does not support sorting")
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue