Handle relationship filter on primary key (#1254)

Co-authored-by: Andreas Donig <git@innwiese.de>
This commit is contained in:
Andreas Donig 2024-06-24 00:20:28 +02:00 committed by GitHub
parent 7f2e7d3ec1
commit 23d504e151
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -2714,29 +2714,39 @@ defmodule Ash.Filter do
|> 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)
if is_list(nested_statement) || is_map(nested_statement) do cond do
case parse_expression(nested_statement, context) do is_list(nested_statement) || is_map(nested_statement) ->
{:ok, nested_expression} -> case parse_expression(nested_statement, context) do
{:ok, BooleanExpression.optimized_new(:and, expression, nested_expression)} {:ok, nested_expression} ->
{:ok, BooleanExpression.optimized_new(:and, expression, nested_expression)}
{:error, error} -> {:error, error} ->
{:error, error} {:error, error}
end end
else
with [field] <- Ash.Resource.Info.primary_key(context.resource), rel.type != :many_to_many && !Map.get(rel, :no_attributes) &&
attribute <- attribute(context, field), [rel.source_attribute] == Ash.Resource.Info.primary_key(rel.destination) ->
{:ok, casted} <- with attr <- attribute(%{public?: true, resource: rel.source}, rel.source_attribute),
Ash.Type.cast_input(attribute.type, nested_statement, attribute.constraints) do %Ash.Resource.Attribute{type: type, constraints: constraints} = attr,
add_expression_part({field, casted}, context, expression) {:ok, casted} <- Ash.Type.cast_input(type, nested_statement, constraints) do
else add_expression_part({attr, casted}, %{context | resource: rel.source}, expression)
_other -> end
{:error,
InvalidFilterValue.exception( true ->
value: inspect(nested_statement), with [field] <- Ash.Resource.Info.primary_key(context.resource),
message: attribute when not is_nil(attribute) <- attribute(context, field),
"a single value must be castable to the primary key of the resource: #{inspect(context.resource)}" {:ok, casted} <-
)} Ash.Type.cast_input(attribute.type, nested_statement, attribute.constraints) do
end add_expression_part({field, casted}, context, expression)
else
_other ->
{:error,
InvalidFilterValue.exception(
value: inspect(nested_statement),
message:
"a single value must be castable to the primary key of the resource: #{inspect(context.resource)}"
)}
end
end end
attr = attribute(context, field) -> attr = attribute(context, field) ->