Confusion with before_transaction timing and doing changes before manage_relationship

Hello, I am basically trying to use the data from a third party API call to create a related resource in manage_relationship. Reading the doc I decided that it would make sense to call the API in a before_transaction hook. The docs is stating the following execution order for a create action:
2. **before_transaction**
4. **Action preparations/validations/change (in order of definition)**
...
7. before_action
...
2. **before_transaction**
4. **Action preparations/validations/change (in order of definition)**
...
7. before_action
...
But from what I'm seeing, my change (containing manage_relationship) is executing before my before_transaction. Here is a reduced example I've quickly set up: (posted below) If I just run for_create, my before_transaction doesn't get executed at all. (the doc for for_create/4 only mentions To have your logic execute only during the action, you can use after_action/2 or before_action/2.), which is already a problem as my manage_relationship depends on the data from the API. If I comment out the crashing code and run a full Ash.create()!, I get the following logs:
iex(6)> Media |> Ash.Changeset.for_create(:add_to_collection, %{"third_party_id" => "id"}) |> Ash.create!()
[info] Change: manage relationship
[info] [private: %{[REDACTED]}]
[info] Change: before transaction
[info] Change: before action
[info] [data: %{name: "name", genre: "unknown"}, private: %{[REDACTED]}]
iex(6)> Media |> Ash.Changeset.for_create(:add_to_collection, %{"third_party_id" => "id"}) |> Ash.create!()
[info] Change: manage relationship
[info] [private: %{[REDACTED]}]
[info] Change: before transaction
[info] Change: before action
[info] [data: %{name: "name", genre: "unknown"}, private: %{[REDACTED]}]
So my "action change" seems to be executed before the "before transaction" which isn't what I understood from the hooks execution order. This leads me to 2 questions: 1. Is there something I'm missing with the execution order of the changes? 2. What would be the correct way of providing data changes to manage_relationship outside the transaction? What I've done for now is to include the manage_relationship inside the before_transaction hook, but then it is never executed until the action is actually ran, and then why not put everything in a normal change then? Thanks 🙂
Solution:
Changes/validations run and then when you call the action before_transaction hooks are the first hooks to run
Jump to solution
12 Replies
ZachDaniel
ZachDaniel•3w ago
Those docs are wrong in that case
Solution
ZachDaniel
ZachDaniel•3w ago
Changes/validations run and then when you call the action before_transaction hooks are the first hooks to run
ZachDaniel
ZachDaniel•3w ago
Can you send me a link to the offending docs?
ZachDaniel
ZachDaniel•3w ago
🥶will put it on my list to fix later today
Lheau
LheauOP•3w ago
So the only reason to use before_transaction, would be to want the code to execute outside the transaction AND not until the actual execution of the action? Which means my changes can't depend on processing done inside before_transaction
ZachDaniel
ZachDaniel•3w ago
Correct Unless they also run in a before_transaction If you want to do things in a change body just keep in mind that it shouldn't have side effects And that in forms, it will run on keypress
Lheau
LheauOP•3w ago
In my case then, doing the manage_relationship inside the before_transaction would then not be some kind of bad practice? I would "only" lose eventual validations for forms on the changes done in there
ZachDaniel
ZachDaniel•3w ago
@Lheau I think the answer to your question is yes
Lheau
LheauOP•3w ago
Thanks for the swift answer 🙂 It's clearer now, I'll see how i'll handle that in the end
ZachDaniel
ZachDaniel•3w ago
fixed the docs 😄 Thank you for pointing that out!
Lheau
LheauOP•3w ago
Thanks! I think the above diagram and detail breakdown also needs to be updated to match your changes (point 6 and 7): https://hexdocs.pm/ash/actions.html#complete-lifecycle-flow

Did you find this page helpful?