diff --git a/lib/ash/actions/aggregate.ex b/lib/ash/actions/aggregate.ex index e263f69b..827e767f 100644 --- a/lib/ash/actions/aggregate.ex +++ b/lib/ash/actions/aggregate.ex @@ -37,11 +37,13 @@ defmodule Ash.Actions.Aggregate do [] ) + resource = query.resource + case aggregate_auth_requests do [] -> case Ash.Query.data_layer_query(query) do {:ok, query} -> - Ash.DataLayer.run_aggregate_query(query, aggregates_in_query, query.resource) + Ash.DataLayer.run_aggregate_query(query, aggregates_in_query, resource) {:error, error} -> {:error, error} @@ -66,7 +68,7 @@ defmodule Ash.Actions.Aggregate do Ash.DataLayer.run_aggregate_query( query, aggregates_in_query, - query.resource + resource ) {:error, error} -> diff --git a/lib/ash/api/interface.ex b/lib/ash/api/interface.ex index 5845f71a..a2600e3f 100644 --- a/lib/ash/api/interface.ex +++ b/lib/ash/api/interface.ex @@ -44,8 +44,8 @@ defmodule Ash.Api.Interface do case Ash.Query.Aggregate.new(query.resource, :count, :count) do {:ok, aggregate} -> case Api.aggregate(__MODULE__, query, aggregate, opts) do - {:ok, value} -> - value + {:ok, %{count: count}} -> + count {:error, error} -> raise Ash.Error.to_error_class(error) @@ -64,7 +64,13 @@ defmodule Ash.Api.Interface do case Ash.Query.Aggregate.new(query.resource, :count, :count) do {:ok, aggregate} -> - Api.aggregate(__MODULE__, query, aggregate, opts) + case Api.aggregate(__MODULE__, query, aggregate, opts) do + {:ok, %{count: count}} -> + {:ok, count} + + {:error, error} -> + {:error, Ash.Error.to_error_class(error)} + end {:error, error} -> {:error, Ash.Error.to_error_class(error)} @@ -78,11 +84,20 @@ defmodule Ash.Api.Interface do def unquote(kind)(query, field, opts \\ []) do query = Ash.Query.to_query(query) - case Ash.Query.Aggregate.new(query.resource, :count, :count, - field: Keyword.put(opts, :field, field) + case Ash.Query.Aggregate.new( + query.resource, + unquote(kind), + unquote(kind), + Keyword.put(opts, :field, field) ) do {:ok, aggregate} -> - Api.aggregate(__MODULE__, query, aggregate, opts) + case Api.aggregate(__MODULE__, query, aggregate, opts) do + {:ok, %{unquote(kind) => value}} -> + {:ok, value} + + {:error, error} -> + {:error, Ash.Error.to_error_class(error)} + end {:error, error} -> {:error, Ash.Error.to_error_class(error)} @@ -96,13 +111,16 @@ defmodule Ash.Api.Interface do def unquote(:"#{kind}!")(query, field, opts \\ []) do query = Ash.Query.to_query(query) - case Ash.Query.Aggregate.new(query.resource, :count, :count, - field: Keyword.put(opts, :field, field) + case Ash.Query.Aggregate.new( + query.resource, + unquote(kind), + unquote(kind), + Keyword.put(opts, :field, field) ) do {:ok, aggregate} -> case Api.aggregate(__MODULE__, query, aggregate, opts) do - {:ok, result} -> - result + {:ok, %{unquote(kind) => value}} -> + value {:error, error} -> raise Ash.Error.to_error_class(error) diff --git a/lib/ash/query/aggregate.ex b/lib/ash/query/aggregate.ex index 3d9e2fda..4cc07d26 100644 --- a/lib/ash/query/aggregate.ex +++ b/lib/ash/query/aggregate.ex @@ -28,6 +28,16 @@ defmodule Ash.Query.Aggregate do @doc false def kinds, do: @kinds + def new!(resource, name, kind, opts \\ []) do + case new(resource, name, kind, opts) do + {:ok, aggregate} -> + aggregate + + {:error, error} -> + raise Ash.Error.to_error_class(error) + end + end + @doc """ Create a new aggregate, used with `Query.aggregate` or `Api.aggregate` @@ -75,7 +85,16 @@ defmodule Ash.Query.Aggregate do attribute_type = if field do related = Ash.Resource.Info.related(resource, relationship) - Ash.Resource.Info.field(related, field).type + + case Ash.Resource.Info.field(related, field) do + %{type: type} -> + {:ok, type} + + _ -> + {:error, "No such field for #{inspect(related)}: #{inspect(field)}"} + end + else + {:ok, nil} end default = @@ -85,7 +104,8 @@ defmodule Ash.Query.Aggregate do default end - with :ok <- validate_path(resource, List.wrap(relationship)), + with {:ok, attribute_type} <- attribute_type, + :ok <- validate_path(resource, List.wrap(relationship)), {:ok, type} <- get_type(kind, type, attribute_type), {:ok, query} <- validate_query(query) do {:ok,