zer3f

zer3f

How to get transaction result of previous forms data of a resource and pass through next resource in AshPhoenix.Form.Submit?

Hello,

I have a form that consists of multiple resources to submit. AshPhoenix.Form helped to render nested forms easily using add_form and submit using AshPhoenix.Form.Submit. But i need some help regarding, getting the pervious value of the form. Please go through these details, this is a registration form that has a flow like this:

  1. Register user
  2. Get the id from the step 1, and add it to user_personal_details (Action already accepts user_id) along with other params like first_name, last_name etc in the resource
  3. Register Company.
  4. Add company id from 3 to update registered user in 1 with company_id.

I have setup all the resources, domains and default actions with relationships. This kind of flow used to do it in a transaction with ecto’s Multi.New() function. But I wonder if I can simplify this process using the existing function AshPhoenix.Form.Submit or any other Ash’s way. Please let me know I need to share source code.

Thank you.

Marked As Solved

zachdaniel

zachdaniel

Creator of Ash

Ah, I see what you mean. Using multiple explicit forms like that only really helps with the form structure itself. You should first be looking at how to implement this logic in your actions, and then work on the form logic, which likely would not require those nested forms once you are ready. Unfortunately I don’t have time to go through your entire code and craft an answer for your specific case, but I can provide a basic example.

# on your user resource

create :register do
  argument :company_name, :string, allow_nil?: false

  change fn changeset, _ -> 
    Ash.Changeset.before_action(changeset, fn changeset, _ -> 
      org = create_organization(changeset.arguments.company_name)
      Ash.Changeset.force_change_attributes(changeset, :company_id, company.id)
    end)
  end
end

Using “hooks” (Ash.Changeset.before_action, Ash.Changeset.after_action, etc.) allow us to build progressively more complex multi-step actions. Additionally, we can use arguments to accept additional inputs that don’t map directly to attributes to be changed.

With that, you can create a single form with all the inputs you need, no need to define nested forms.

Using manage_relationship

Given that what you are doing is essentially creating related data as part of an action, there is a builtin that can help with this, called manage_relationship.

You can use it like so:

create :register do
  argument :personal_information, :map, allow_nil?: false
  argument :company_information, :map, allow_nil?: false

  change manage_relationship(:personal_information, type: :create)
  change manage_relationship(:personal_information, type: :create)
end

Then, when creating your form, you can use auto?: true, which will automatically detect the necessary nested forms. The two in combination should be all you need to accomplish your stated goal.

AshPhoenix.Form.for_create(
  Mgx.Accounts.User,
  :register_with_password,
  forms: [
    auto?: true
  ]
)
|> AshPhoenix.Form.add_form([:personal_information])
|> AshPhoenix.Form.add_form([:company_information])
|> to_form()

Also Liked

zer3f

zer3f

I see, Now I understood the flow of it. Thank you. Much appreciated.

Where Next?

Popular in Questions Top

greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
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
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 41989 114
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New

We're in Beta

About us Mission Statement