moxley

moxley

Using `in` or `is_nil()` for a jsonb property

I’m trying to understand the Ash filter expression syntax for working with json arrays within a jsonb column in ash_postgres.

I have a jsonb column, settings, on a table notification_settings

For a simple equality expression, I can use the == operator:

NotificationSettings
|> Ash.Query.filter(settings["foo"] == "bar")
|> Ash.read!(authorize?: false)

But for a value in enum expression:

NotificationSettings
|> Ash.Query.filter("email" in settings["dues_reminders"])
|> Ash.read!(authorize?: false)

It produces:

** (Ash.Error.Unknown)
Bread Crumbs:
  > Error returned from: NotificationSettings.read
Unknown Error
* ** (Postgrex.Error) ERROR 22P02 (invalid_text_representation) malformed array literal: "["email"]". If you are trying to query a JSON field, the parameter may need to be interpolated. Instead of
    p.json["field"] != "value"
do
    p.json["field"] != ^"value"
"[" must introduce explicitly-specified array dimensions.

So I have to use fragment() instead:

NotificationSettings
|> Ash.Query.filter(fragment("?->'dues_reminders' \\? ?", settings, "email"))
|> Ash.read!(authorize?: false)

A very similar thing happens with is_nil() on a jsonb property:

NotificationSettings
|> Ash.Query.filter(is_nil(settings["dues_reminders"]))
|> Ash.read!(authorize?: false)

It produces:

* ** (Postgrex.Error) ERROR 22P02 (invalid_text_representation) malformed array literal: "["email"]"...

For that too, I must use fragment instead:

NotificationSettings
|> Ash.Query.filter(fragment("?->'dues_reminders' is null", settings))
|> Ash.read!(authorize?: false)

Is this correct? Is there no built-in syntax for doing jsonb value comparisons beyond the == operator?

First Post!

zachdaniel

zachdaniel

Creator of Ash

I believe this is a bug. Please open an issue and I will investigate :slight_smile:

Last Post!

Where Next?

Popular in Questions Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New

Other popular topics Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 49084 226
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New

We're in Beta

About us Mission Statement