weljoda
Using actor_id in atomic Change causes sql error
Hey there I’m giving Ash my first try and like it pretty well so far. I’m trying to implement a bulk update but run into a SQL error and I can only guess the problem. I have the following Change, similar to the one in the book:
defmodule CourseManager.Chat.Changes.AddUserToSeenBy do
use Ash.Resource.Change
@impl true
def init(opts), do: {:ok, opts}
@impl true
def atomic(_changeset, _opts, context) do
if context.actor do
actor_id = context.actor.id
{:atomic,
%{
seen_by:
{:atomic,
expr(
fragment(
"array_prepend(?, array_remove(?, ?))",
^actor_id,
seen_by,
^actor_id
)
)}
}}
else
:ok
end
end
end
And the attribute:
attribute :seen_by, {:array, :uuid} do
description "Array of user IDs who have seen this message"
default []
public? true
end
The bulk_update didn’t work, so I tried a single update, but I get the following error:
[debug] QUERY ERROR source="messages" db=1.5ms queue=0.3ms idle=25.3ms
UPDATE "messages" AS m0 SET "updated_at" = (CASE WHEN (array_prepend($1, array_remove(m0."seen_by"::uuid[], $2)))::uuid[] != m0."seen_by"::uuid[] THEN $3::timestamp ELSE m0."updated_at"::timestamp END)::timestamp, "seen_by" = (array_prepend($4, array_remove(m0."seen_by"::uuid[], $5)))::uuid[] WHERE (m0."id"::uuid = $6::uuid) RETURNING m0."id", m0."message", m0."deleted", m0."reactions", m0."seen_by", m0."inserted_at", m0."updated_at", m0."user_id", m0."course_id", m0."parent_message_id" ["71a3f79a-62f6-49c3-8c43-d7d82ab6fd1c", "71a3f79a-62f6-49c3-8c43-d7d82ab6fd1c", ~U[2025-07-28 16:35:28.369137Z], "71a3f79a-62f6-49c3-8c43-d7d82ab6fd1c", "71a3f79a-62f6-49c3-8c43-d7d82ab6fd1c", "b6a170f6-0373-460f-acef-77ae9e76bb72"]
When I put the query in pgadmin and applying the arguments, I only have to use single quotes to make it work correctly.
Is it possible that the PG typecheck fails because the actor_id is not passed as a uuid but as a string instead?
Can anyone give me some advice how to proceed?
Thanks
Marked As Solved
zachdaniel
Hmm…it could be related to that. You don’t see any other errors? Something you can try as an experiment is transforming the actor_id to a binary before providing it. Or you could try:
type(^actor_id, :uuid) in place of just referencing the actor id.
Also Liked
weljoda
Amazing, thanks very much
. It did the trick.
fragment(
"array_prepend(?, array_remove(?, ?))",
type(^actor_id, :uuid),
seen_by,
type(^actor_id, :uuid)
)
Last Post!
weljoda
Amazing, thanks very much
. It did the trick.
fragment(
"array_prepend(?, array_remove(?, ?))",
type(^actor_id, :uuid),
seen_by,
type(^actor_id, :uuid)
)
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex









