Skip to content

Commit

Permalink
fix: properly load doubly nested calculation's explicit dependencies
Browse files Browse the repository at this point in the history
fixes #1720
  • Loading branch information
zachdaniel committed Jan 18, 2025
1 parent 98341ad commit d166299
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 15 deletions.
39 changes: 25 additions & 14 deletions lib/ash/query/query.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1488,23 +1488,34 @@ defmodule Ash.Query do
module = calculation.module
opts = calculation.opts

resource_calculation_load =
if resource_calculation do
if resource_calculation do
resource_calculation_load =
List.wrap(resource_calculation.load)
else
[]
end

loads =
module.load(
query,
opts,
Map.put(calculation.context, :context, query.context)
)
|> Ash.Actions.Helpers.validate_calculation_load!(module)
|> Enum.concat(resource_calculation_load)
loads =
module.load(
query,
opts,
Map.put(calculation.context, :context, query.context)
)
|> Ash.Actions.Helpers.validate_calculation_load!(module)
|> Enum.concat(resource_calculation_load)

%{calculation | required_loads: loads}
%{calculation | required_loads: loads}
else
loads =
module.load(
query,
opts,
Map.put(calculation.context, :context, query.context)
)
|> Ash.Actions.Helpers.validate_calculation_load!(module)

%{
calculation
| required_loads: Enum.concat(List.wrap(loads), List.wrap(calculation.required_loads))
}
end
end

defp fetch_key(map, key) when is_map(map) do
Expand Down
39 changes: 38 additions & 1 deletion test/calculations/expr_calculation_with_related_dep_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ defmodule Ash.Test.ExprCalculationWithRelatedDepTest do
end

relationships do
belongs_to :account, Account do
belongs_to :account, Ash.Test.ExprCalculationWithRelatedDepTest.Account do
public? true
allow_nil? false
end
Expand Down Expand Up @@ -81,6 +81,32 @@ defmodule Ash.Test.ExprCalculationWithRelatedDepTest do

calculations do
calculate(:balance, :integer, expr(related_account.balance))

calculate :related_account_account_count, :integer do
load related_account: :account

calculation fn accounts, ctx ->
accounts
|> Enum.map(fn account ->
if match?(%Ash.NotLoaded{}, account.related_account.account) do
raise "nested dep not loaded"
end

Enum.count(List.wrap(account.related_account.account))
end)
end
end

calculate :double_related_account_account_count, :integer do
load :related_account_account_count

calculation fn accounts, ctx ->
accounts
|> Enum.map(fn account ->
account.related_account_account_count * 2
end)
end
end
end

relationships do
Expand All @@ -99,4 +125,15 @@ defmodule Ash.Test.ExprCalculationWithRelatedDepTest do

assert Ash.load!(account, :balance, authorize?: true, actor: %{a: :b}).balance == 10
end

test "can load nested calculation dependences from function calculations" do
account2 =
Ash.Seed.seed!(Account2, %{type: :test, balance_attr: 10})

account = Ash.Seed.seed!(Account, %{related_account: account2})

account = account |> Ash.load!(:double_related_account_account_count)

assert account.double_related_account_account_count == 2
end
end

0 comments on commit d166299

Please sign in to comment.