improvement: allow select/load callbacks for calcs to return irrelevant keys

test: add a test case for nested required calculations
This commit is contained in:
Zach Daniel 2022-10-04 00:22:40 -04:00
parent e7847501f7
commit dd6fd1fbc3
2 changed files with 28 additions and 0 deletions

View file

@ -838,6 +838,7 @@ defmodule Ash.Query do
|> Kernel.||([])
|> Enum.concat(module.select(query, opts, calculation.context) || [])
|> Enum.uniq()
|> Enum.filter(&Ash.Resource.Info.attribute(query.resource, &1))
loads =
module.load(
@ -847,6 +848,7 @@ defmodule Ash.Query do
)
|> Ash.Actions.Helpers.validate_calculation_load!(module)
|> Enum.concat(List.wrap(resource_calculation.load))
|> Enum.reject(&Ash.Resource.Info.attribute(query.resource, &1))
calculation = %{
calculation
@ -933,6 +935,7 @@ defmodule Ash.Query do
|> Kernel.||([])
|> Enum.concat(module.select(query, opts, calculation.context) || [])
|> Enum.uniq()
|> Enum.filter(&Ash.Resource.Info.attribute(query.resource, &1))
loads =
module.load(
@ -942,6 +945,7 @@ defmodule Ash.Query do
)
|> Ash.Actions.Helpers.validate_calculation_load!(module)
|> Enum.concat(List.wrap(resource_calculation.load))
|> Enum.reject(&Ash.Resource.Info.attribute(query.resource, &1))
calculation = %{
calculation
@ -1421,6 +1425,7 @@ defmodule Ash.Query do
|> module.select(opts, calculation.context)
|> List.wrap()
|> Enum.concat(calculation.select)
|> Enum.filter(&Ash.Resource.Info.attribute(query.resource, &1))
loads =
module.load(
@ -1430,6 +1435,7 @@ defmodule Ash.Query do
)
|> Ash.Actions.Helpers.validate_calculation_load!(module)
|> Enum.concat(List.wrap(calculation.required_loads))
|> Enum.reject(&Ash.Resource.Info.attribute(query.resource, &1))
calculation = %{calculation | select: fields_to_select, required_loads: loads}
%{query | calculations: Map.put(query.calculations, name, calculation)}

View file

@ -39,6 +39,10 @@ defmodule Ash.Test.CalculationTest do
opts[:keys]
end
def select(_query, opts, _) do
opts[:keys]
end
def calculate(records, opts, _) do
Enum.map(records, fn record ->
Enum.map_join(opts[:keys], " ", fn key ->
@ -94,6 +98,10 @@ defmodule Ash.Test.CalculationTest do
:string,
{ConcatWithLoad, keys: [:full_name, :full_name]}
calculate :full_name_plus_full_name_plus_full_name,
:string,
{ConcatWithLoad, keys: [:full_name, :full_name_plus_full_name]}
calculate :slug, :string, expr(full_name <> "123"), load: [:full_name]
calculate :expr_full_name, :string, expr(first_name <> " " <> last_name) do
@ -202,6 +210,20 @@ defmodule Ash.Test.CalculationTest do
assert full_names == ["brian cranston brian cranston", "zach daniel zach daniel"]
end
test "it loads anything specified by the load callback, even when nested" do
full_names =
User
|> Ash.Query.load(:full_name_plus_full_name_plus_full_name)
|> Api.read!()
|> Enum.map(& &1.full_name_plus_full_name_plus_full_name)
|> Enum.sort()
assert full_names == [
"brian cranston brian cranston brian cranston",
"zach daniel zach daniel zach daniel"
]
end
test "it doesn't reload anything specified by the load callback if its already been loaded when using `lazy?: true`" do
full_names =
User