fix: require calculations specified on resource load

This commit is contained in:
Zach Daniel 2022-05-17 11:54:02 -04:00
parent c963b349fd
commit 5e270288e6
3 changed files with 22 additions and 14 deletions

View file

@ -1116,9 +1116,18 @@ defmodule Ash.Actions.Read do
) do ) do
all_calcs = Enum.map(all_calcs, & &1.name) all_calcs = Enum.map(all_calcs, & &1.name)
resource_load =
if resource_calculation = Ash.Resource.Info.calculation(resource, calculation.name) do
List.wrap(resource_calculation.load)
else
[]
end
dependencies = dependencies =
query query
|> calculation.module.load(calculation.opts, calculation.context) |> calculation.module.load(calculation.opts, calculation.context)
|> List.wrap()
|> Enum.concat(resource_load)
|> Ash.Actions.Helpers.validate_calculation_load!(calculation.module) |> Ash.Actions.Helpers.validate_calculation_load!(calculation.module)
|> Enum.map(fn |> Enum.map(fn
{key, _} -> {key, _} ->

View file

@ -181,7 +181,7 @@ defmodule Ash.Filter do
statement, statement,
aggregates \\ %{}, aggregates \\ %{},
calculations \\ %{}, calculations \\ %{},
context \\ %{} _context \\ %{}
) do ) do
context = %{ context = %{
resource: resource, resource: resource,
@ -189,8 +189,7 @@ defmodule Ash.Filter do
aggregates: aggregates, aggregates: aggregates,
calculations: calculations, calculations: calculations,
public?: true, public?: true,
data_layer: Ash.DataLayer.data_layer(resource), data_layer: Ash.DataLayer.data_layer(resource)
query_context: context
} }
with {:ok, expression} <- parse_expression(statement, context), with {:ok, expression} <- parse_expression(statement, context),
@ -263,15 +262,14 @@ defmodule Ash.Filter do
{:ok, nil} {:ok, nil}
end end
def parse(resource, statement, aggregates, calculations, context) do def parse(resource, statement, aggregates, calculations, _context) do
context = %{ context = %{
resource: resource, resource: resource,
relationship_path: [], relationship_path: [],
aggregates: aggregates, aggregates: aggregates,
calculations: calculations, calculations: calculations,
public?: false, public?: false,
data_layer: Ash.DataLayer.data_layer(resource), data_layer: Ash.DataLayer.data_layer(resource)
query_context: context
} }
with {:ok, expression} <- parse_expression(statement, context), with {:ok, expression} <- parse_expression(statement, context),
@ -1772,7 +1770,6 @@ defmodule Ash.Filter do
resource: related, resource: related,
aggregates: context.aggregates, aggregates: context.aggregates,
calculations: context.calculations, calculations: context.calculations,
query_context: context.query_context,
public?: context.public? public?: context.public?
} }
@ -1863,10 +1860,6 @@ defmodule Ash.Filter do
context context
|> Map.update!(:relationship_path, fn path -> path ++ [rel.name] end) |> Map.update!(:relationship_path, fn path -> path ++ [rel.name] end)
|> Map.put(:resource, rel.destination) |> Map.put(:resource, rel.destination)
|> Map.update!(
:query_context,
&Ash.Helpers.deep_merge_maps(&1 || %{}, rel.context || %{})
)
if is_list(nested_statement) || is_map(nested_statement) do if is_list(nested_statement) || is_map(nested_statement) do
case parse_expression(nested_statement, context) do case parse_expression(nested_statement, context) do
@ -1978,7 +1971,7 @@ defmodule Ash.Filter do
module, module,
opts, opts,
resource_calculation.type, resource_calculation.type,
Map.put(args, :context, context.query_context), args,
resource_calculation.filterable?, resource_calculation.filterable?,
resource_calculation.load resource_calculation.load
) do ) do
@ -2149,7 +2142,7 @@ defmodule Ash.Filter do
module, module,
opts, opts,
resource_calculation.type, resource_calculation.type,
Map.put(args, :context, Map.get(context, :query_context, %{})), args,
resource_calculation.filterable?, resource_calculation.filterable?,
resource_calculation.load resource_calculation.load
) do ) do
@ -2253,7 +2246,7 @@ defmodule Ash.Filter do
module, module,
opts, opts,
resource_calculation.type, resource_calculation.type,
Map.put(args, :context, context.query_context), args,
resource_calculation.filterable?, resource_calculation.filterable?,
resource_calculation.load resource_calculation.load
) do ) do

View file

@ -94,6 +94,8 @@ defmodule Ash.Test.CalculationTest do
:string, :string,
{ConcatWithLoad, keys: [:full_name, :full_name]} {ConcatWithLoad, keys: [:full_name, :full_name]}
calculate :slug, :string, expr(full_name <> "123"), load: [:full_name]
calculate :expr_full_name, :string, expr(first_name <> " " <> last_name) do calculate :expr_full_name, :string, expr(first_name <> " " <> last_name) do
allow_async? true allow_async? true
end end
@ -179,6 +181,10 @@ defmodule Ash.Test.CalculationTest do
assert full_names == ["brian cranston", "zach daniel"] assert full_names == ["brian cranston", "zach daniel"]
end end
test "loads dependencies", %{user1: user} do
assert %{slug: "zach daniel123"} = Api.load!(user, [:slug])
end
test "it loads anything specified by the load callback" do test "it loads anything specified by the load callback" do
full_names = full_names =
User User