mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 05:23:03 +12:00
fix: pull aggregate values properly
This commit is contained in:
parent
81dcbf1bdf
commit
920dff7f00
2 changed files with 64 additions and 45 deletions
|
@ -249,40 +249,46 @@ defmodule Ash.Actions.Read do
|
||||||
data = fetched_data[:results]
|
data = fetched_data[:results]
|
||||||
load_paths = query.context.load_paths
|
load_paths = query.context.load_paths
|
||||||
initial_query = query.context.initial_query
|
initial_query = query.context.initial_query
|
||||||
|
aggregate_value_request_paths = fetched_data[:aggregate_value_request_paths] || []
|
||||||
|
|
||||||
case Enum.filter(load_paths, fn path ->
|
if !Enum.empty?(aggregate_value_request_paths) &&
|
||||||
!get_in(context, path ++ [:data])
|
!get_in(context, path ++ [:aggregate_values]) do
|
||||||
end) do
|
{:new_deps, aggregate_value_request_paths}
|
||||||
[] ->
|
else
|
||||||
data
|
case Enum.filter(load_paths, fn path ->
|
||||||
|> Load.attach_loads(get_in(context, [:data, :fetch, :load]) || %{})
|
!get_in(context, path ++ [:data])
|
||||||
|> add_aggregate_values(
|
end) do
|
||||||
query.aggregates,
|
[] ->
|
||||||
query.resource,
|
data
|
||||||
Map.get(fetched_data, :aggregate_values) || %{},
|
|> Load.attach_loads(get_in(context, [:data, :fetch, :load]) || %{})
|
||||||
Map.get(fetched_data, :aggregates_in_query) || []
|
|> add_aggregate_values(
|
||||||
)
|
query.aggregates,
|
||||||
|> add_calculation_values(
|
query.resource,
|
||||||
Map.get(fetched_data, :ultimate_query) || query,
|
get_in(context, path ++ [:aggregate_values]) || %{},
|
||||||
Map.get(fetched_data, :calculations_at_runtime) || []
|
Map.get(fetched_data, :aggregates_in_query) || []
|
||||||
)
|
)
|
||||||
|> case do
|
|> add_calculation_values(
|
||||||
{:ok, values} ->
|
Map.get(fetched_data, :ultimate_query) || query,
|
||||||
values
|
Map.get(fetched_data, :calculations_at_runtime) || []
|
||||||
|> add_tenant(query)
|
)
|
||||||
|> add_page(
|
|> case do
|
||||||
action,
|
{:ok, values} ->
|
||||||
Map.get(fetched_data, :count),
|
values
|
||||||
query.sort,
|
|> add_tenant(query)
|
||||||
initial_query,
|
|> add_page(
|
||||||
Keyword.put(query_opts, :page, query.context[:page_opts])
|
action,
|
||||||
)
|
Map.get(fetched_data, :count),
|
||||||
|> add_query(Map.get(fetched_data, :ultimate_query), request_opts)
|
query.sort,
|
||||||
|> unwrap_for_get(get?)
|
initial_query,
|
||||||
end
|
Keyword.put(query_opts, :page, query.context[:page_opts])
|
||||||
|
)
|
||||||
|
|> add_query(Map.get(fetched_data, :ultimate_query), request_opts)
|
||||||
|
|> unwrap_for_get(get?)
|
||||||
|
end
|
||||||
|
|
||||||
deps ->
|
deps ->
|
||||||
{:new_deps, Enum.map(deps, &(&1 ++ [:data]))}
|
{:new_deps, Enum.map(deps, &(&1 ++ [:data]))}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
)
|
)
|
||||||
|
@ -568,7 +574,9 @@ defmodule Ash.Actions.Read do
|
||||||
%{
|
%{
|
||||||
results: request_opts[:initial_data],
|
results: request_opts[:initial_data],
|
||||||
aggregates_in_query: aggregates_in_query,
|
aggregates_in_query: aggregates_in_query,
|
||||||
calculations_at_runtime: calculations_at_runtime
|
calculations_at_runtime: calculations_at_runtime,
|
||||||
|
aggregate_value_request_paths:
|
||||||
|
Enum.map(aggregate_value_requests, &(&1.path ++ [:data]))
|
||||||
},
|
},
|
||||||
%{
|
%{
|
||||||
requests: aggregate_value_requests
|
requests: aggregate_value_requests
|
||||||
|
@ -606,7 +614,7 @@ defmodule Ash.Actions.Read do
|
||||||
{:ok, query} <- query,
|
{:ok, query} <- query,
|
||||||
{:ok, filter} <-
|
{:ok, filter} <-
|
||||||
filter_with_related(Enum.map(filter_requests, & &1.path), ash_query, data),
|
filter_with_related(Enum.map(filter_requests, & &1.path), ash_query, data),
|
||||||
filter <- update_aggregate_filters(filter, data),
|
filter <- update_aggregate_filters(filter, data, path),
|
||||||
{:ok, query} <-
|
{:ok, query} <-
|
||||||
Ash.DataLayer.set_context(
|
Ash.DataLayer.set_context(
|
||||||
ash_query.resource,
|
ash_query.resource,
|
||||||
|
@ -674,7 +682,9 @@ defmodule Ash.Actions.Read do
|
||||||
ultimate_query: ultimate_query,
|
ultimate_query: ultimate_query,
|
||||||
count: count,
|
count: count,
|
||||||
calculations_at_runtime: calculations_at_runtime,
|
calculations_at_runtime: calculations_at_runtime,
|
||||||
aggregates_in_query: aggregates_in_query
|
aggregates_in_query: aggregates_in_query,
|
||||||
|
aggregate_value_request_paths:
|
||||||
|
Enum.map(aggregate_value_requests, &(&1.path ++ [:data]))
|
||||||
},
|
},
|
||||||
%{
|
%{
|
||||||
notifications: after_notifications,
|
notifications: after_notifications,
|
||||||
|
@ -686,7 +696,9 @@ defmodule Ash.Actions.Read do
|
||||||
results: results,
|
results: results,
|
||||||
count: count,
|
count: count,
|
||||||
calculations_at_runtime: calculations_at_runtime,
|
calculations_at_runtime: calculations_at_runtime,
|
||||||
aggregates_in_query: aggregates_in_query
|
aggregates_in_query: aggregates_in_query,
|
||||||
|
aggregate_value_request_paths:
|
||||||
|
Enum.map(aggregate_value_requests, &(&1.path ++ [:data]))
|
||||||
},
|
},
|
||||||
%{
|
%{
|
||||||
notifications: after_notifications,
|
notifications: after_notifications,
|
||||||
|
@ -717,11 +729,14 @@ defmodule Ash.Actions.Read do
|
||||||
|
|
||||||
defp validate_get(_, _, _), do: :ok
|
defp validate_get(_, _, _), do: :ok
|
||||||
|
|
||||||
defp update_aggregate_filters(filter, data) do
|
defp update_aggregate_filters(filter, data, path) do
|
||||||
Filter.update_aggregates(filter, fn aggregate, ref ->
|
Filter.update_aggregates(filter, fn aggregate, ref ->
|
||||||
case data[:aggregate][ref.relationship_path ++ aggregate.relationship_path][
|
case get_in(
|
||||||
:authorization_filter
|
data,
|
||||||
] do
|
path ++
|
||||||
|
[:aggregate, ref.relationship_path] ++
|
||||||
|
aggregate.relationship_path ++ [:authorization_filter]
|
||||||
|
) do
|
||||||
nil ->
|
nil ->
|
||||||
aggregate
|
aggregate
|
||||||
|
|
||||||
|
@ -1111,10 +1126,14 @@ defmodule Ash.Actions.Read do
|
||||||
|
|
||||||
defp add_aggregate_values(results, aggregates, resource, aggregate_values, aggregates_in_query) do
|
defp add_aggregate_values(results, aggregates, resource, aggregate_values, aggregates_in_query) do
|
||||||
keys_to_aggregates =
|
keys_to_aggregates =
|
||||||
Enum.reduce(aggregate_values, %{}, fn {_name, keys_to_values}, acc ->
|
Enum.reduce(aggregate_values, %{}, fn
|
||||||
Enum.reduce(keys_to_values, acc, fn {pkey, values}, acc ->
|
{_name, %{data: keys_to_values}}, acc ->
|
||||||
Map.update(acc, pkey, values, &Map.merge(&1, values))
|
Enum.reduce(keys_to_values, acc, fn {pkey, values}, acc ->
|
||||||
end)
|
Map.update(acc, pkey, values, &Map.merge(&1, values))
|
||||||
|
end)
|
||||||
|
|
||||||
|
_, acc ->
|
||||||
|
acc
|
||||||
end)
|
end)
|
||||||
|
|
||||||
pkey = Ash.Resource.Info.primary_key(resource)
|
pkey = Ash.Resource.Info.primary_key(resource)
|
||||||
|
|
|
@ -281,7 +281,7 @@ defmodule Ash.Query.Aggregate do
|
||||||
resource: aggregate_resource,
|
resource: aggregate_resource,
|
||||||
api: initial_query.api,
|
api: initial_query.api,
|
||||||
query: aggregate_query(related, reverse_relationship, request_path),
|
query: aggregate_query(related, reverse_relationship, request_path),
|
||||||
path: [:aggregate_values, relationship_path],
|
path: request_path ++ [:aggregate_values, relationship_path],
|
||||||
action: Ash.Resource.Info.primary_action(aggregate_resource, :read),
|
action: Ash.Resource.Info.primary_action(aggregate_resource, :read),
|
||||||
name: "fetch aggregate: #{Enum.join(relationship_path, ".")}",
|
name: "fetch aggregate: #{Enum.join(relationship_path, ".")}",
|
||||||
data:
|
data:
|
||||||
|
|
Loading…
Reference in a new issue