improvement: properly handle context for referenced calculations

This commit is contained in:
Zach Daniel 2023-07-20 21:57:44 -04:00
parent 042b83cf3b
commit 97a9ca5872
2 changed files with 47 additions and 8 deletions

View file

@ -733,7 +733,7 @@ defmodule AshPostgres.Aggregate do
query = AshPostgres.DataLayer.default_bindings(query, aggregate.resource)
ref = %Ash.Query.Ref{
attribute: Ash.Resource.Info.field(resource, aggregate.field),
attribute: aggregate_field(aggregate, resource, relationship_path, query),
relationship_path: relationship_path,
resource: query.__ash_bindings__.resource
}
@ -824,7 +824,7 @@ defmodule AshPostgres.Aggregate do
)
ref = %Ash.Query.Ref{
attribute: Ash.Resource.Info.field(resource, aggregate.field),
attribute: aggregate_field(aggregate, resource, relationship_path, query),
relationship_path: relationship_path,
resource: query.__ash_bindings__.resource
}
@ -909,11 +909,7 @@ defmodule AshPostgres.Aggregate do
query = AshPostgres.DataLayer.default_bindings(query, aggregate.resource)
ref = %Ash.Query.Ref{
attribute:
Ash.Resource.Info.field(
resource,
aggregate.field || List.first(Ash.Resource.Info.primary_key(resource))
),
attribute: aggregate_field(aggregate, resource, relationship_path, query),
relationship_path: relationship_path,
resource: resource
}
@ -1030,4 +1026,34 @@ defmodule AshPostgres.Aggregate do
relationship = Ash.Resource.Info.relationship(resource, relationship)
relationship.type == :belongs_to && single_path?(relationship.destination, rest)
end
defp aggregate_field(aggregate, resource, _relationship_path, query) do
case Ash.Resource.Info.field(
resource,
aggregate.field || List.first(Ash.Resource.Info.primary_key(resource))
) do
%Ash.Resource.Calculation{calculation: {module, opts}} = calculation ->
calc_type =
AshPostgres.Types.parameterized_type(
calculation.type,
Map.get(calculation, :constraints, [])
)
AshPostgres.Expr.validate_type!(query, calc_type, "#{inspect(calculation.name)}")
{:ok, query_calc} =
Ash.Query.Calculation.new(
calculation.name,
module,
opts,
calculation.type,
Map.get(aggregate, :context, %{})
)
query_calc
other ->
other
end
end
end

View file

@ -805,6 +805,18 @@ defmodule AshPostgres.Expr do
)
end
defp do_dynamic_expr(
_query,
%Ref{
attribute: %Ash.Resource.Calculation{} = calculation
},
_bindings,
_embedded?,
_type
) do
raise "cannot build expression from resource calculation! #{calculation.name}"
end
defp do_dynamic_expr(
query,
%Ref{attribute: %Ash.Query.Aggregate{} = aggregate} = ref,
@ -1338,7 +1350,8 @@ defmodule AshPostgres.Expr do
defp maybe_uuid_to_binary(_type, _value, original_value), do: original_value
defp validate_type!(query, type, context) do
@doc false
def validate_type!(query, type, context) do
case type do
{:parameterized, Ash.Type.CiStringWrapper.EctoType, _} ->
require_extension!(query, "citext", context)