fix: properly load calcs/aggs on manual relationships

It needs to be optimized, but it will do the trick for now.
This commit is contained in:
Zach Daniel 2022-10-13 00:36:29 -04:00
parent 48d96fc417
commit 362180190c
3 changed files with 67 additions and 2 deletions

View file

@ -510,7 +510,8 @@ defmodule Ash.Actions.Load do
related_query,
request_opts,
fn ->
mod.load(data, opts, %{
data
|> mod.load(opts, %{
relationship: relationship,
query: related_query,
root_query: root_query,
@ -519,6 +520,29 @@ defmodule Ash.Actions.Load do
api: related_query.api,
tenant: related_query.tenant
})
|> case do
{:ok, result} ->
# TODO: this will result in quite a few requests potentially for aggs/calcs
# This should be optimized.
Enum.reduce_while(result, {:ok, %{}}, fn {key, records}, {:ok, acc} ->
case related_query.api.load(records, %{related_query | load: []},
lazy?: true,
tenant: related_query.tenant,
actor: request_opts[:actor],
authorize?: request_opts[:authorize?],
tracer: request_opts[:tracer]
) do
{:ok, results} ->
{:cont, {:ok, Map.put(acc, key, results)}}
{:error, error} ->
{:halt, {:error, error}}
end
end)
{:error, error} ->
{:error, error}
end
end
)
end)

View file

@ -9,7 +9,7 @@ defmodule Ash.Flow.Step.Transaction do
output: [
type: :any,
doc:
"Which step or steps to use when constructing the output list. Defaults to the last step.",
"Which step or steps to use when constructing the output. Defaults to the last step.",
links: []
],
timeout: [

View file

@ -99,6 +99,10 @@ defmodule Ash.Test.Actions.AsyncLoadTest do
source_attribute_on_join_resource: :post_id
end
calculations do
calculate :title_plus_title, :string, expr((title || "foo") <> (title || "bar"))
end
policies do
policy action(:authorized_actor) do
authorize_if expr(actor_id == ^actor(:id))
@ -316,6 +320,43 @@ defmodule Ash.Test.Actions.AsyncLoadTest do
|> Enum.flat_map(&Map.get(&1, :posts_in_same_category))
end
test "it allows loading calculations on and through manual relationships" do
post1 =
Post
|> new(%{title: "post1", category: "foo"})
|> Api.create!()
Post
|> new(%{title: "post2", category: "bar"})
|> Api.create!()
Post
|> new(%{title: "post2", category: "foo"})
|> Api.create!()
assert %Post{
title: "post1",
title_plus_title: "post1post1",
posts_in_same_category: [
%{
title: "post2",
title_plus_title: "post2post2",
posts_in_same_category: [
%{title: "post1", title_plus_title: "post1post1"}
]
}
]
} =
post1
|> Api.load!([
:title_plus_title,
posts_in_same_category: [
:title_plus_title,
posts_in_same_category: [:title_plus_title]
]
])
end
test "it allows loading related data" do
author =
Author