mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 13:33:20 +12:00
fix: properly handle "bare" references, and track it for potential later use
This commit is contained in:
parent
80833c3f58
commit
91d3bf314a
2 changed files with 56 additions and 29 deletions
|
@ -234,7 +234,7 @@ defmodule Ash.Filter do
|
|||
filter
|
||||
|
||||
{:error, error} ->
|
||||
raise error
|
||||
raise Ash.Error.to_error_class(error)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -296,7 +296,13 @@ defmodule Ash.Filter do
|
|||
field =
|
||||
case ref.attribute do
|
||||
field when is_atom(field) ->
|
||||
Ash.Resource.Info.field(resource, field)
|
||||
case Ash.Resource.Info.field(resource, field) do
|
||||
nil ->
|
||||
field
|
||||
|
||||
field ->
|
||||
field
|
||||
end
|
||||
|
||||
field ->
|
||||
field
|
||||
|
@ -307,36 +313,46 @@ defmodule Ash.Filter do
|
|||
|
||||
errors =
|
||||
refs
|
||||
|> Enum.flat_map(fn ref ->
|
||||
field = ref.attribute
|
||||
|> Enum.flat_map(fn
|
||||
%{attribute: attribute, relationship_path: relationship_path} when is_atom(attribute) ->
|
||||
[
|
||||
NoSuchAttributeOrRelationship.exception(
|
||||
attribute_or_relationship: attribute,
|
||||
resource: Ash.Resource.Info.related(resource, relationship_path)
|
||||
)
|
||||
]
|
||||
|
||||
# This handles manually added calcualtions and aggregates
|
||||
case Map.fetch(field, :filterable?) do
|
||||
:error ->
|
||||
[]
|
||||
ref ->
|
||||
field = ref.attribute
|
||||
|
||||
{:ok, true} ->
|
||||
[]
|
||||
|
||||
{:ok, false} ->
|
||||
[Ash.Error.Query.InvalidFilterReference.exception(field: field.name)]
|
||||
|
||||
{:ok, :simple_equality} ->
|
||||
if ref.simple_equality? do
|
||||
# This handles manually added calcualtions and aggregates
|
||||
case Map.fetch(field, :filterable?) do
|
||||
:error ->
|
||||
[]
|
||||
else
|
||||
[
|
||||
Ash.Error.Query.InvalidFilterReference.exception(
|
||||
field: field.name,
|
||||
simple_equality?: true
|
||||
)
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
{:ok, true} ->
|
||||
[]
|
||||
|
||||
{:ok, false} ->
|
||||
[Ash.Error.Query.InvalidFilterReference.exception(field: field.name)]
|
||||
|
||||
{:ok, :simple_equality} ->
|
||||
if ref.simple_equality? do
|
||||
[]
|
||||
else
|
||||
[
|
||||
Ash.Error.Query.InvalidFilterReference.exception(
|
||||
field: field.name,
|
||||
simple_equality?: true
|
||||
)
|
||||
]
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
multiple_filter_errors =
|
||||
refs
|
||||
|> Enum.filter(&is_map(&1.attribute))
|
||||
|> Enum.filter(fn ref ->
|
||||
Map.fetch(ref.attribute, :filterable?) == {:ok, :simple_equality}
|
||||
end)
|
||||
|
@ -1675,8 +1691,15 @@ defmodule Ash.Filter do
|
|||
defp attribute(%{public?: true, resource: resource}, attribute),
|
||||
do: Ash.Resource.Info.public_attribute(resource, attribute)
|
||||
|
||||
defp attribute(%{public?: false, resource: resource}, attribute),
|
||||
do: Ash.Resource.Info.attribute(resource, attribute)
|
||||
defp attribute(%{public?: false, resource: resource}, attribute) do
|
||||
case Ash.Resource.Info.attribute(resource, attribute) do
|
||||
nil ->
|
||||
raise "what"
|
||||
|
||||
attr ->
|
||||
attr
|
||||
end
|
||||
end
|
||||
|
||||
defp aggregate(%{public?: true, resource: resource}, aggregate),
|
||||
do: Ash.Resource.Info.public_aggregate(resource, aggregate)
|
||||
|
@ -1782,6 +1805,10 @@ defmodule Ash.Filter do
|
|||
end
|
||||
end
|
||||
|
||||
defp add_expression_part(%Ref{} = ref, _context, _expression) do
|
||||
{:ok, %{ref | bare?: true}}
|
||||
end
|
||||
|
||||
defp add_expression_part({%Ref{} = ref, nested_statement}, context, expression) do
|
||||
case related(context, ref.relationship_path) do
|
||||
nil ->
|
||||
|
@ -2314,7 +2341,7 @@ defmodule Ash.Filter do
|
|||
new_ref = %{
|
||||
ref
|
||||
| relationship_path: ref.relationship_path ++ [relationship.name],
|
||||
attribute: Ash.Resource.Info.attribute(relationship.destination, key),
|
||||
attribute: attribute(%{context | resource: relationship.destination}, key),
|
||||
resource: relationship.destination
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
defmodule Ash.Query.Ref do
|
||||
@moduledoc "Represents a relation/attribute reference"
|
||||
defstruct [:attribute, :relationship_path, :resource, :simple_equality?]
|
||||
defstruct [:attribute, :relationship_path, :resource, :simple_equality?, :bare?]
|
||||
|
||||
defimpl Inspect do
|
||||
def inspect(ref, _opts) do
|
||||
|
|
Loading…
Reference in a new issue