An aggregate field loaded in create action isn't available for pub_sub?

publish :create, ["update", :aggregate_field1] in one of my resources fails with the following error, despite the fact that change load(:aggregate_field1) is in the action definition. If I remove the publish setting from pub_sub, the create action succeeds, with the :aggregate_field1 properly loaded to the changeset. I wonder if something changed about how pub_sub works in Ash lately, because my pub_sub and create action codes used to work fine. I did recently update ash to the latest version. Thanks.
42 Replies
Jason
JasonOP2y ago
commit []
↳ anonymous fn/3 in Ash.Changeset.with_hooks/3, at: lib/ash/changeset/changeset.ex:1733
[debug] QUERY OK source="signups" db=18.1ms queue=0.1ms idle=1655.6ms
SELECT s0."id", i1."aggregate_field1" FROM "signups" AS s0 LEFT OUTER JOIN "public"."items" AS i1 ON s0."item_id" = i1."id" WHERE (s0."id"::uuid = $1::uuid) ["33b1d69d-14a8-413c-83c2-613961d43c5b"]
↳ AshPostgres.DataLayer.run_query/2, at: lib/data_layer.ex:628
** (Protocol.UndefinedError) protocol String.Chars not implemented for #Ash.NotLoaded<:aggregate> of type Ash.NotLoaded (a struct). This protocol is implemented for the following type(s): Ash.CiString, Ato..
(elixir 1.14.1) lib/string/chars.ex:3: String.Chars.impl_for!/1
(elixir 1.14.1) lib/string/chars.ex:22: String.Chars.to_string/1
(elixir 1.14.1) lib/enum.ex:3991: Enum.join_non_empty_list/3
(elixir 1.14.1) lib/enum.ex:4272: Enum.join_list/2
(elixir 1.14.1) lib/enum.ex:1658: Enum."-map/2-lists^map/1-0-"/2
(ash 2.9.25) lib/ash/notifier/pub_sub/pub_sub.ex:216: Ash.Notifier.PubSub.fill_template/2
(ash 2.9.25) lib/ash/notifier/pub_sub/pub_sub.ex:143: Ash.Notifier.PubSub.publish_notification/2
(elixir 1.14.1) lib/enum.ex:975: Enum."-each/2-lists^foreach/1-0-"/2

commit []
↳ anonymous fn/3 in Ash.Changeset.with_hooks/3, at: lib/ash/changeset/changeset.ex:1733
[debug] QUERY OK source="signups" db=18.1ms queue=0.1ms idle=1655.6ms
SELECT s0."id", i1."aggregate_field1" FROM "signups" AS s0 LEFT OUTER JOIN "public"."items" AS i1 ON s0."item_id" = i1."id" WHERE (s0."id"::uuid = $1::uuid) ["33b1d69d-14a8-413c-83c2-613961d43c5b"]
↳ AshPostgres.DataLayer.run_query/2, at: lib/data_layer.ex:628
** (Protocol.UndefinedError) protocol String.Chars not implemented for #Ash.NotLoaded<:aggregate> of type Ash.NotLoaded (a struct). This protocol is implemented for the following type(s): Ash.CiString, Ato..
(elixir 1.14.1) lib/string/chars.ex:3: String.Chars.impl_for!/1
(elixir 1.14.1) lib/string/chars.ex:22: String.Chars.to_string/1
(elixir 1.14.1) lib/enum.ex:3991: Enum.join_non_empty_list/3
(elixir 1.14.1) lib/enum.ex:4272: Enum.join_list/2
(elixir 1.14.1) lib/enum.ex:1658: Enum."-map/2-lists^map/1-0-"/2
(ash 2.9.25) lib/ash/notifier/pub_sub/pub_sub.ex:216: Ash.Notifier.PubSub.fill_template/2
(ash 2.9.25) lib/ash/notifier/pub_sub/pub_sub.ex:143: Ash.Notifier.PubSub.publish_notification/2
(elixir 1.14.1) lib/enum.ex:975: Enum."-each/2-lists^foreach/1-0-"/2

(ash 2.9.25) lib/ash/notifier/notifier.ex:35: anonymous fn/3 in Ash.Notifier.notify/1
(elixir 1.14.1) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3
(ash 2.9.25) lib/ash/notifier/notifier.ex:34: anonymous fn/3 in Ash.Notifier.notify/1
(elixir 1.14.1) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3
(ash 2.9.25) lib/ash/notifier/notifier.ex:31: anonymous fn/2 in Ash.Notifier.notify/1
(elixir 1.14.1) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3
(ash 2.9.25) lib/ash/notifier/notifier.ex:30: Ash.Notifier.notify/1
(ash 2.9.25) lib/ash/engine/engine.ex:904: Ash.Engine.add_resource_notification/2
(ash 2.9.25) lib/ash/engine/engine.ex:642: Ash.Engine.fully_advance_request/2
(ash 2.9.25) lib/ash/engine/engine.ex:578: Ash.Engine.do_run_iteration/2
(elixir 1.14.1) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3
iex:22: (file)
(ash 2.9.25) lib/ash/notifier/notifier.ex:35: anonymous fn/3 in Ash.Notifier.notify/1
(elixir 1.14.1) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3
(ash 2.9.25) lib/ash/notifier/notifier.ex:34: anonymous fn/3 in Ash.Notifier.notify/1
(elixir 1.14.1) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3
(ash 2.9.25) lib/ash/notifier/notifier.ex:31: anonymous fn/2 in Ash.Notifier.notify/1
(elixir 1.14.1) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3
(ash 2.9.25) lib/ash/notifier/notifier.ex:30: Ash.Notifier.notify/1
(ash 2.9.25) lib/ash/engine/engine.ex:904: Ash.Engine.add_resource_notification/2
(ash 2.9.25) lib/ash/engine/engine.ex:642: Ash.Engine.fully_advance_request/2
(ash 2.9.25) lib/ash/engine/engine.ex:578: Ash.Engine.do_run_iteration/2
(elixir 1.14.1) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3
iex:22: (file)
@Zach Daniel can you please give me some pointers as to how to troubleshoot this?
ZachDaniel
ZachDaniel2y ago
So, aggregates are not automatically loaded by the publishing logic I think that’s something we could actually improve, but until then in order to use them like that you have to make sure they are always loaded. And actually yeah I just realized what broke them 🤔 Are you using change load to load required data for your notifiers?
Jason
JasonOP2y ago
yes
ZachDaniel
ZachDaniel2y ago
yeah, okay, I broke this functionality, my apologies Can you open an issue on ash core and I'll fix it ASAP?
Jason
JasonOP2y ago
Sure. Thanks!!
Jason
JasonOP2y ago
GitHub
Aggregates loaded in the action is not available for publishing · I...
Describe the bug A clear and concise description of what the bug is. aggregates loaded via change load[:aggregate_field] is showing up as nil when publish :create, ["update_signup", :aggr...
ZachDaniel
ZachDaniel2y ago
Hey, so actually looking at the code I think this actually ought to work? Or maybe I don't understand the issue as well as I thought I did. what type of action are you noticing this for? nvm I can see from your example its a create action and you have change load(:aggregate_field1) in the :create action?
Jason
JasonOP2y ago
yes, that's right.
ZachDaniel
ZachDaniel2y ago
are you on the latest version of ash? I saw you upgraded recently but how recently 😆 we move quick As you know
Jason
JasonOP2y ago
2.9.25 If I comment out the publish :create ... line, the action successfully completes, with the aggregate loaded to changeset properly
ZachDaniel
ZachDaniel2y ago
okay, interesting 🤔
Jason
JasonOP2y ago
That makes me feel comfortable about the other part of the code.
ZachDaniel
ZachDaniel2y ago
Yeah, so it should be pretty isolated to the creation of notifications ah, okay I found it 😄 can you try main to confirm the fix?
Jason
JasonOP2y ago
Sure. one sec Hmm... still getting the same error. Interestingly, the aggregate field isn't loaded at all, even with publish ... commented out. Almost as if change load[... is ignored.
ZachDaniel
ZachDaniel2y ago
hrm... something there is very strange are you sure you're doing things the same? Or that the main that you're using is latest? Basically all I changed was one line:
{:ok, result, Map.put(instructions, :notification_data, result)}
I didn't change the return value, so the aggregate should definitely still be loaded if it was before...
Jason
JasonOP2y ago
mix deps shows ash 2.10, so that's good
ZachDaniel
ZachDaniel2y ago
your mix.exs points at the github tho right?
Jason
JasonOP2y ago
no... I saw 2.10 was the same as main. 😦 let me try github *I thought 2.10 was the same
ZachDaniel
ZachDaniel2y ago
yeah, new commits are on the main branch in GH 🙂 although still concerning if 2.10 it wasn't even loading at all but lets just see what happens on the GH version, if it all works then it can just be released and we can move on 😆
Jason
JasonOP2y ago
unfortunately, no change from my earlier attempt. same error. and the aggregate is not loaded to the changeset. fyi. I have this at the bottom of the create action to see what the changeset looks like.
change load([:sheet_id])

change fn changeset, _ ->
IO.inspect(changeset, label: "changeset in create ###########")
end
change load([:sheet_id])

change fn changeset, _ ->
IO.inspect(changeset, label: "changeset in create ###########")
end
ZachDaniel
ZachDaniel2y ago
ah 🙂 when you say its not loaded into the changeset WDYM? what do you see inspected on the changeset?
Jason
JasonOP2y ago
sheet_id: #Ash.NotLoaded<:aggregate>,
ZachDaniel
ZachDaniel2y ago
yeah, that makes sense though if its in the data key of the changeset thats the before Its actually not possible to, within the action, inspect something that has been loaded by change load because we do it after all the action steps are done
Jason
JasonOP2y ago
I see.
ZachDaniel
ZachDaniel2y ago
so you'd need to run the create yourself and inspect it Either way, I think what this means is just that I haven't fixed the original bug
Jason
JasonOP2y ago
I will try to look at the pub sub notification code to see if I can figure it out as well.
ZachDaniel
ZachDaniel2y ago
I wouldn't worry about it 🙂 Its deeper than that, unfortunately I'll have it fixed shortly, just got it reproduced in a test
Jason
JasonOP2y ago
nice !!
ZachDaniel
ZachDaniel2y ago
okay, main is ready to try again 🙂
Jason
JasonOP2y ago
Got it It's working! Thank you! @Zach Daniel Same situation but this time the update action is using manual. and change load([:sheet_id]) where :sheet_id is coming from a belongs_to relationship, seems to be ignored, and I'm getting this error again. Does that make sense?
protocol String.Chars not implemented for #Ash.NotLoaded<:aggregate> of type Ash.NotLoaded (a struct)
protocol String.Chars not implemented for #Ash.NotLoaded<:aggregate> of type Ash.NotLoaded (a struct)
update :manual_update do

change load([:sheet_id])

manual fn changeset, _ ->
...
Ecto.Query....
|> Repo.update_all(set: ....)

{:ok, changeset.data}
end
update :manual_update do

change load([:sheet_id])

manual fn changeset, _ ->
...
Ecto.Query....
|> Repo.update_all(set: ....)

{:ok, changeset.data}
end
pub_sub do
publish :manual_update, ["update_sheet", :sheet_id]
pub_sub do
publish :manual_update, ["update_sheet", :sheet_id]
ZachDaniel
ZachDaniel2y ago
does this happen on the latest published ash rc version?
Jason
JasonOP2y ago
let me try. Yes, rc.2 produces the same result.
ZachDaniel
ZachDaniel2y ago
what if you do change select(:sheet_id) ?
Jason
JasonOP2y ago
let me try same issue
ZachDaniel
ZachDaniel2y ago
can you try main? I've just pushed some stuff up
Jason
JasonOP2y ago
sure sorry, no luck I see where you made changes, I will try to do some debugging on my end as well.
ZachDaniel
ZachDaniel2y ago
Try main now 🙂 We had some other bugs along a similar vein
Jason
JasonOP2y ago
okay! Sorry, still the same error. using * ash 2.11.0-rc.3 ([email protected]:ash-project/ash.git) (mix) locked at db375ef
ZachDaniel
ZachDaniel2y ago
🤔 🤔 🤔 do you have this replicated when its not a manual action?
Jason
JasonOP2y ago
This doesn't happen if it's not a manual action.
ZachDaniel
ZachDaniel2y ago
Okay, thanks. I’ve been a bit strapped for time lately. If you have a chance to reproduce this behavior in a test in Ash that would be very helpful
Jason
JasonOP2y ago
Sure. will try.

Did you find this page helpful?