Ash Query filter function

For background information I have binary field in my datalayer called token when I call this the following function:
%{id: id} = user = insert(:user)

assert {:ok, %My_App.Ash.User{id: ^id} = _user} =
User
|> Ash.Query.filter(token == user.token)
|> My_App.Ash.read_one()
%{id: id} = user = insert(:user)

assert {:ok, %My_App.Ash.User{id: ^id} = _user} =
User
|> Ash.Query.filter(token == user.token)
|> My_App.Ash.read_one()
but I keep running into the same error highlighted below after inspection.
#Ash.Query<
resource: My_App.Ash.User,
errors: [
%Ash.Error.Unknown.UnknownError{
error: "filter: Invalid reference user.confirmation_token at relationship_path [:user]",
field: nil,
changeset: nil,
query: nil,
error_context: [],
vars: [],
path: [:filter],
stacktrace: #Stacktrace<>,
class: :unknown
}
]
>
#Ash.Query<
resource: My_App.Ash.User,
errors: [
%Ash.Error.Unknown.UnknownError{
error: "filter: Invalid reference user.confirmation_token at relationship_path [:user]",
field: nil,
changeset: nil,
query: nil,
error_context: [],
vars: [],
path: [:filter],
stacktrace: #Stacktrace<>,
class: :unknown
}
]
>
token exists on resource user , I don't know what the problem is ?
11 Replies
edwinofdawn
edwinofdawnOP•3y ago
follow up if try and pull_out the token then pin it in my query like below:
%{id: id, token: token} = user = insert(:user)


assert {:ok, _user}
|> Ash.Query.filter(token == ^token)
|> My_App.Ash.read_one()
%{id: id, token: token} = user = insert(:user)


assert {:ok, _user}
|> Ash.Query.filter(token == ^token)
|> My_App.Ash.read_one()
the error changes to (Postgrex.Error) ERROR 22021 (character_not_in_repertoire) invalid byte sequence for encoding "UTF8": 0x97
ZachDaniel
ZachDaniel•3y ago
👋 So you can do Ash.Query.fitler(query, token == ^user.token), don't necessarily need to pull it out to pin it What data type is your token?
moxley
moxley•3y ago
Hey @Zach Daniel. I'm working with @edwinofdawn on this. I think we have it figured it out. The token column was a binary type. I kept on running into problems with the binary type, so I changed it to a string type, and encoded the input value to base64 before writing it to the DB. While I was still trying to get it to work as a binary type, I was getting this error:
== Compilation error in file lib/gf_web/graphql/absinthe_schema.ex ==
** (RuntimeError) Could not determine graphql field type for Ash.Type.Binary on GF.Ash.Customer.confirmation_token

If this is a custom type, you can add `def graphql_type/1` to your type to define the graphql type.
If this is not your type, you will need to use `types` or `attribute_types` or `attribute_input_types`
to configure the type for any field using this type. If this is an `Ash.Type.NewType`, you may need to define
`graphql_type` and `graphql_input_type`s for it.
== Compilation error in file lib/gf_web/graphql/absinthe_schema.ex ==
** (RuntimeError) Could not determine graphql field type for Ash.Type.Binary on GF.Ash.Customer.confirmation_token

If this is a custom type, you can add `def graphql_type/1` to your type to define the graphql type.
If this is not your type, you will need to use `types` or `attribute_types` or `attribute_input_types`
to configure the type for any field using this type. If this is an `Ash.Type.NewType`, you may need to define
`graphql_type` and `graphql_input_type`s for it.
I thought maybe I need to make the attribute private? true. That didn't make any difference. But now thinking about this further, maybe writable? false would have eliminated that error?
ZachDaniel
ZachDaniel•3y ago
private? true should have done it
moxley
moxley•3y ago
Strange
ZachDaniel
ZachDaniel•3y ago
🤔 if you can get that error again can you show me a stacktrace/any other context for it?
moxley
moxley•3y ago
(ash_graphql 0.23.1) lib/resource/resource.ex:3434: AshGraphql.Resource.get_specific_field_type/4
(ash_graphql 0.23.1) lib/resource/resource.ex:1196: anonymous fn/3 in AshGraphql.Resource.read_args/3
(elixir 1.14.3) lib/enum.ex:1658: Enum."-map/2-lists^map/1-0-"/2
(ash_graphql 0.23.1) lib/resource/resource.ex:1064: AshGraphql.Resource.args/5
(ash_graphql 0.23.1) lib/resource/resource.ex:407: anonymous fn/6 in AshGraphql.Resource.queries/5
(elixir 1.14.3) lib/enum.ex:1658: Enum."-map/2-lists^map/1-0-"/2
(elixir 1.14.3) lib/enum.ex:4249: Enum.flat_map_list/2
lib/gf_web/graphql/absinthe_schema.ex:5: GF.Ash.AshTypes.run/2
(absinthe 1.7.0) lib/absinthe/pipeline.ex:384: Absinthe.Pipeline.run_phase/3
(absinthe 1.7.0) lib/absinthe/schema.ex:360: Absinthe.Schema.__after_compile__/2
(stdlib 4.2) lists.erl:1350: :lists.foldl/3
(elixir 1.14.3) lib/kernel/parallel_compiler.ex:340: anonymous fn/5 in Kernel.ParallelCompiler.spawn_workers/7
(ash_graphql 0.23.1) lib/resource/resource.ex:3434: AshGraphql.Resource.get_specific_field_type/4
(ash_graphql 0.23.1) lib/resource/resource.ex:1196: anonymous fn/3 in AshGraphql.Resource.read_args/3
(elixir 1.14.3) lib/enum.ex:1658: Enum."-map/2-lists^map/1-0-"/2
(ash_graphql 0.23.1) lib/resource/resource.ex:1064: AshGraphql.Resource.args/5
(ash_graphql 0.23.1) lib/resource/resource.ex:407: anonymous fn/6 in AshGraphql.Resource.queries/5
(elixir 1.14.3) lib/enum.ex:1658: Enum."-map/2-lists^map/1-0-"/2
(elixir 1.14.3) lib/enum.ex:4249: Enum.flat_map_list/2
lib/gf_web/graphql/absinthe_schema.ex:5: GF.Ash.AshTypes.run/2
(absinthe 1.7.0) lib/absinthe/pipeline.ex:384: Absinthe.Pipeline.run_phase/3
(absinthe 1.7.0) lib/absinthe/schema.ex:360: Absinthe.Schema.__after_compile__/2
(stdlib 4.2) lists.erl:1350: :lists.foldl/3
(elixir 1.14.3) lib/kernel/parallel_compiler.ex:340: anonymous fn/5 in Kernel.ParallelCompiler.spawn_workers/7
ZachDaniel
ZachDaniel•3y ago
okay, gotcha So that looks like its the arguments to a read action So do you have a "get by token" read action? That would be another place to change from binary -> string (and in fact, you probably want to accept a string there anyway since you generally can't get binaries over gql) Even if the token is a binary in the db
moxley
moxley•3y ago
Yeah, there is a read :get_by_confirmation_token, but it wasn't being used in my test.
ZachDaniel
ZachDaniel•3y ago
Yeah, but the graphql schema gets built fully at compile time
moxley
moxley•3y ago
I think I'll leave the column as a string, and base64 encode the value. That's working well, and we won't need to write any conversion logic on read that way.

Did you find this page helpful?