Filtering by enum attribute

I have an Ash resource that has an enum field status. Im using AshJsonApi to pass in a filter: filter[status]=active,incomplete. This doesnt seem to work out of the box so I implemented a preperation where I do this:
defp filter_by_status(query) do
case Ash.Changeset.get_argument(query, :filter) do
%{"status" => statuses} ->
all_statuses = String.split(statuses, ",")
Ash.Query.filter(query, status in ^all_statuses)

_ ->
query
end
end
defp filter_by_status(query) do
case Ash.Changeset.get_argument(query, :filter) do
%{"status" => statuses} ->
all_statuses = String.split(statuses, ",")
Ash.Query.filter(query, status in ^all_statuses)

_ ->
query
end
end
This does not work however, returns the following error:
[error] FrameworkError: Framework Error | something went wrong. Error messaging is incomplete so far: %Ash.Error.Query.InvalidFilterValue{message: nil, value: "active,incomplete", context: #Ecto.Query<from m0 in MembershipService.Memberships.Membership, as: 0, where: type(as(0).status, {:parameterized, Ash.Type.Atom.EctoType, []}) ==
type(
^"active,incomplete",
{:parameterized, Ash.Type.Atom.EctoType,
one_of: [:active, :canceled, :incomplete, :incomplete_expired, :trialing, :past_due, :unpaid]}
), where: type(as(0).status, {:parameterized, Ash.Type.Atom.EctoType, []}) in [
type(
^"active",
{:parameterized, Ash.Type.Atom.EctoType,
one_of: [:active, :canceled, :incomplete, :incomplete_expired, :trialing, :past_due, :unpaid]}
),
type(
^"incomplete",
{:parameterized, Ash.Type.Atom.EctoType,
one_of: [:active, :canceled, :incomplete, :incomplete_expired, :trialing, :past_due, :unpaid]}
)
],
[error] FrameworkError: Framework Error | something went wrong. Error messaging is incomplete so far: %Ash.Error.Query.InvalidFilterValue{message: nil, value: "active,incomplete", context: #Ecto.Query<from m0 in MembershipService.Memberships.Membership, as: 0, where: type(as(0).status, {:parameterized, Ash.Type.Atom.EctoType, []}) ==
type(
^"active,incomplete",
{:parameterized, Ash.Type.Atom.EctoType,
one_of: [:active, :canceled, :incomplete, :incomplete_expired, :trialing, :past_due, :unpaid]}
), where: type(as(0).status, {:parameterized, Ash.Type.Atom.EctoType, []}) in [
type(
^"active",
{:parameterized, Ash.Type.Atom.EctoType,
one_of: [:active, :canceled, :incomplete, :incomplete_expired, :trialing, :past_due, :unpaid]}
),
type(
^"incomplete",
{:parameterized, Ash.Type.Atom.EctoType,
one_of: [:active, :canceled, :incomplete, :incomplete_expired, :trialing, :past_due, :unpaid]}
)
],
Is there an example or an way to filter by an enum?
5 Replies
gordoneliel
gordonelielOP2y ago
Inspecting the filter after adding my customer status filter, it looks like there is an original filter to find status but the direct string sent from the api through AshJsonApi:
filter: #Ash.Filter<status == "active,incomplete" and status in [:active,
:incomplete]>,
filter: #Ash.Filter<status == "active,incomplete" and status in [:active,
:incomplete]>,
ZachDaniel
ZachDaniel2y ago
filter[status][in][0]=active&filter[status][in][1]=incomplete should do it
gordoneliel
gordonelielOP2y ago
Do I have to write a custom filter expression for this or can it be handled automatically? Getting an error when running with the array filter:
rror: "filter: Could not cast expression: Ash.Query.Operator.In status %{\"0\" => \"active\", \"1\" => \"incomplete\"}",
rror: "filter: Could not cast expression: Ash.Query.Operator.In status %{\"0\" => \"active\", \"1\" => \"incomplete\"}",
Whats also odd is that in the example repos for ash, the case on get_argument for filter has atom keys, but mine has string keys 🧐
ZachDaniel
ZachDaniel2y ago
that should be fine... I think this may be something we're missing in ash_json_api, we should be handling list query params like that properly and creating lists can you open a bug in ash_json_api? I can fix it when I get the chance
gordoneliel
gordonelielOP2y ago
Added! In case anyone else runs into this, to filter by multiple values in an enum attribute, you need to filters your query params like so filter[status][in]=a&filter[status][in]=b where a & b are possible enum values

Did you find this page helpful?