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)
|
attribute = Ash.Resource.Info.attribute(resource, field)
|
||||||
|
|
||||||
cond do
|
cond do
|
||||||
|
aggregate = Ash.Resource.Info.aggregate(resource, field) ->
|
||||||
|
aggregate_sort(aggregates, aggregate, order, resource, sorts, errors)
|
||||||
|
|
||||||
Map.has_key?(aggregates, field) ->
|
Map.has_key?(aggregates, field) ->
|
||||||
aggregate_sort(aggregates, field, order, resource, sorts, errors)
|
aggregate_sort(aggregates, field, order, resource, sorts, errors)
|
||||||
|
|
||||||
|
@ -94,7 +97,7 @@ defmodule Ash.Actions.Sort do
|
||||||
end
|
end
|
||||||
|
|
||||||
!attribute ->
|
!attribute ->
|
||||||
{sorts, [NoSuchAttribute.exception(attribute: field) | errors]}
|
{sorts, [NoSuchAttribute.exception(name: field) | errors]}
|
||||||
|
|
||||||
Ash.Type.embedded_type?(attribute.type) ->
|
Ash.Type.embedded_type?(attribute.type) ->
|
||||||
{sorts, ["Cannot sort on embedded types" | errors]}
|
{sorts, ["Cannot sort on embedded types" | errors]}
|
||||||
|
@ -141,16 +144,38 @@ defmodule Ash.Actions.Sort do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp aggregate_sort(aggregates, field, order, resource, sorts, errors) do
|
defp aggregate_sort(aggregates, field, order, resource, sorts, errors) do
|
||||||
aggregate = Map.get(aggregates, field)
|
{field, type} =
|
||||||
|
case field do
|
||||||
|
field when is_atom(field) ->
|
||||||
|
aggregate = Map.get(aggregates, field)
|
||||||
|
|
||||||
if Ash.DataLayer.data_layer_can?(resource, :aggregate_sort) &&
|
{field, {:ok, aggregate.type}}
|
||||||
Ash.DataLayer.data_layer_can?(
|
|
||||||
resource,
|
%Ash.Resource.Aggregate{} = agg ->
|
||||||
{:sort, Ash.Type.storage_type(aggregate.type)}
|
field_type =
|
||||||
) do
|
if agg.field do
|
||||||
{sorts ++ [{field, order}], errors}
|
related = Ash.Resource.Info.related(resource, agg.relationship_path)
|
||||||
else
|
Ash.Resource.Info.attribute(related, agg.field).type
|
||||||
{sorts, [AggregatesNotSupported.exception(resource: resource, feature: "sorting") | errors]}
|
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(type)}
|
||||||
|
) do
|
||||||
|
{sorts ++ [{field, order}], errors}
|
||||||
|
else
|
||||||
|
{sorts,
|
||||||
|
[AggregatesNotSupported.exception(resource: resource, feature: "sorting") | errors]}
|
||||||
|
end
|
||||||
|
|
||||||
|
{:error, error} ->
|
||||||
|
{sorts, [error | errors]}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1541,16 +1541,25 @@ defmodule Ash.Query do
|
||||||
query = to_query(query)
|
query = to_query(query)
|
||||||
|
|
||||||
if Ash.DataLayer.data_layer_can?(query.resource, :sort) do
|
if Ash.DataLayer.data_layer_can?(query.resource, :sort) do
|
||||||
sorts
|
query_with_sort =
|
||||||
|> List.wrap()
|
sorts
|
||||||
|> Enum.reduce(query, fn
|
|> List.wrap()
|
||||||
{sort, direction}, query ->
|
|> Enum.reduce(query, fn
|
||||||
%{query | sort: query.sort ++ [{sort, direction}]}
|
{sort, direction}, query ->
|
||||||
|
%{query | sort: query.sort ++ [{sort, direction}]}
|
||||||
|
|
||||||
sort, query ->
|
sort, query ->
|
||||||
%{query | sort: query.sort ++ [{sort, :asc}]}
|
%{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)
|
end)
|
||||||
|> validate_sort()
|
|
||||||
else
|
else
|
||||||
add_error(query, :sort, "Data layer does not support sorting")
|
add_error(query, :sort, "Data layer does not support sorting")
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue