mirror of
https://github.com/ash-project/ash.git
synced 2024-09-19 21:13:10 +12:00
fix: when hydrating nested aggregates, use correct related resource/path pair
closes #1213
This commit is contained in:
parent
4910bf9d6d
commit
fbcafa1bfa
2 changed files with 140 additions and 14 deletions
|
@ -2789,16 +2789,17 @@ defmodule Ash.Actions.Read do
|
||||||
field = add_calc_context(field, actor, authorize?, tenant, tracer, domain)
|
field = add_calc_context(field, actor, authorize?, tenant, tracer, domain)
|
||||||
|
|
||||||
if authorize? && field.authorize? do
|
if authorize? && field.authorize? do
|
||||||
authorize_aggregate(
|
{:ok,
|
||||||
field,
|
authorize_aggregate(
|
||||||
path_filters,
|
field,
|
||||||
actor,
|
path_filters,
|
||||||
authorize?,
|
actor,
|
||||||
tenant,
|
authorize?,
|
||||||
tracer,
|
tenant,
|
||||||
domain,
|
tracer,
|
||||||
ref_path
|
domain,
|
||||||
)
|
ref_path
|
||||||
|
)}
|
||||||
else
|
else
|
||||||
{:ok, agg}
|
{:ok, agg}
|
||||||
end
|
end
|
||||||
|
@ -2849,15 +2850,15 @@ defmodule Ash.Actions.Read do
|
||||||
end
|
end
|
||||||
|
|
||||||
%Ash.Resource.Aggregate{} = resource_aggregate ->
|
%Ash.Resource.Aggregate{} = resource_aggregate ->
|
||||||
related_resource =
|
agg_related_resource =
|
||||||
Ash.Resource.Info.related(related_resource, ref_path ++ aggregate.relationship_path)
|
Ash.Resource.Info.related(related_resource, resource_aggregate.relationship_path)
|
||||||
|
|
||||||
read_action =
|
read_action =
|
||||||
resource_aggregate.read_action ||
|
resource_aggregate.read_action ||
|
||||||
Ash.Resource.Info.primary_action!(related_resource, :read).name
|
Ash.Resource.Info.primary_action!(agg_related_resource, :read).name
|
||||||
|
|
||||||
with %{valid?: true} = aggregate_query <-
|
with %{valid?: true} = aggregate_query <-
|
||||||
Ash.Query.for_read(related_resource, read_action),
|
Ash.Query.for_read(agg_related_resource, read_action),
|
||||||
%{valid?: true} = aggregate_query <-
|
%{valid?: true} = aggregate_query <-
|
||||||
Ash.Query.Aggregate.build_query(aggregate_query,
|
Ash.Query.Aggregate.build_query(aggregate_query,
|
||||||
filter: resource_aggregate.filter,
|
filter: resource_aggregate.filter,
|
||||||
|
|
125
test/actions/calculations_referencing_aggregates_test.exs
Normal file
125
test/actions/calculations_referencing_aggregates_test.exs
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
defmodule Ash.Test.Actions.CalculationsReferenceAggregatesTest do
|
||||||
|
@moduledoc false
|
||||||
|
use ExUnit.Case, async: true
|
||||||
|
|
||||||
|
defmodule One do
|
||||||
|
use Ash.Resource,
|
||||||
|
data_layer: Ash.DataLayer.Ets,
|
||||||
|
domain: Ash.Test.Actions.CalculationsReferenceAggregatesTest.Domain
|
||||||
|
|
||||||
|
ets do
|
||||||
|
private? true
|
||||||
|
end
|
||||||
|
|
||||||
|
actions do
|
||||||
|
defaults [:read]
|
||||||
|
end
|
||||||
|
|
||||||
|
relationships do
|
||||||
|
belongs_to :two, Ash.Test.Actions.CalculationsReferenceAggregatesTest.Two
|
||||||
|
end
|
||||||
|
|
||||||
|
attributes do
|
||||||
|
uuid_primary_key :id
|
||||||
|
attribute :quantity, :integer, allow_nil?: false, public?: true, constraints: [min: 0]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defmodule Two do
|
||||||
|
use Ash.Resource,
|
||||||
|
data_layer: Ash.DataLayer.Ets,
|
||||||
|
domain: Ash.Test.Actions.CalculationsReferenceAggregatesTest.Domain
|
||||||
|
|
||||||
|
ets do
|
||||||
|
private? true
|
||||||
|
end
|
||||||
|
|
||||||
|
attributes do
|
||||||
|
uuid_primary_key :id
|
||||||
|
end
|
||||||
|
|
||||||
|
actions do
|
||||||
|
defaults [:read]
|
||||||
|
end
|
||||||
|
|
||||||
|
relationships do
|
||||||
|
has_many :one, One
|
||||||
|
end
|
||||||
|
|
||||||
|
aggregates do
|
||||||
|
sum :total_quantity, :one, :quantity, default: 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defmodule Three do
|
||||||
|
use Ash.Resource,
|
||||||
|
data_layer: Ash.DataLayer.Ets,
|
||||||
|
domain: Ash.Test.Actions.CalculationsReferenceAggregatesTest.Domain
|
||||||
|
|
||||||
|
ets do
|
||||||
|
private? true
|
||||||
|
end
|
||||||
|
|
||||||
|
actions do
|
||||||
|
defaults [:read]
|
||||||
|
end
|
||||||
|
|
||||||
|
attributes do
|
||||||
|
uuid_primary_key :id
|
||||||
|
end
|
||||||
|
|
||||||
|
relationships do
|
||||||
|
belongs_to :two, Two
|
||||||
|
belongs_to :four, Ash.Test.Actions.CalculationsReferenceAggregatesTest.Four
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defmodule Four do
|
||||||
|
use Ash.Resource,
|
||||||
|
data_layer: Ash.DataLayer.Ets,
|
||||||
|
domain: Ash.Test.Actions.CalculationsReferenceAggregatesTest.Domain
|
||||||
|
|
||||||
|
ets do
|
||||||
|
private? true
|
||||||
|
end
|
||||||
|
|
||||||
|
actions do
|
||||||
|
defaults [:read, :create]
|
||||||
|
end
|
||||||
|
|
||||||
|
attributes do
|
||||||
|
uuid_primary_key :id
|
||||||
|
end
|
||||||
|
|
||||||
|
relationships do
|
||||||
|
has_many :three, Three
|
||||||
|
end
|
||||||
|
|
||||||
|
calculations do
|
||||||
|
# This throws
|
||||||
|
calculate :total_quantity,
|
||||||
|
:integer,
|
||||||
|
expr(sum(three.two, field: :total_quantity) || 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defmodule Domain do
|
||||||
|
use Ash.Domain
|
||||||
|
|
||||||
|
resources do
|
||||||
|
resource One
|
||||||
|
resource Two
|
||||||
|
resource Three
|
||||||
|
resource Four
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "loading calculations that reference aggregates" do
|
||||||
|
Four
|
||||||
|
|> Ash.create!(%{})
|
||||||
|
|> Ash.load!(:total_quantity)
|
||||||
|
|> Map.get(:total_quantity)
|
||||||
|
|> Kernel.==(0)
|
||||||
|
|> assert()
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue