Problem with ash_phoenix.gen.live and form_to extensions

I am working with the new Ash Framework book from PragPro but create the project from scratch.

I generated a form_component via mix ash_phoenix.gen.live --domain Tuneshg.Music --resource Tuneshg.Music.Artist --resourceplural artists

At first, I used the form = AshPhoenix.Form.for_create() function to create a new artist.

Later on I learned, that I could create these functions via AshPhoenix-Extensions.
That got me: form = Tuneshg.Music.form_to_create_artist()

When using this new function, the app crashed, when validating the input.

Deeper inspection showed, that the params ended to the validate function differ.
When using
AshPhoenix.Form.for_create():

HANDLE EVENT "validate" in TuneshgWeb.ArtistLive.Index
Component: TuneshgWeb.ArtistLive.FormComponent
Parameters: %{"_target" => ["artist", "biography"], "artist" => %{"biography" => "my_biography", "name" => "my_name"}}

When using
Tuneshg.Music.form_to_create_artist():

HANDLE EVENT "validate" in TuneshgWeb.ArtistLive.Index
Component: TuneshgWeb.ArtistLive.FormComponent
 Parameters: %{"_target" => ["form", "name"], "form" => %{"_unused_biography" => "", "_unused_name" => "", "biography" => "", "name" => "m"}}

Why do these two ways produce different params?
Is this intentional or is it a bug?

And if it is intentional, what is the intention?

Thanks for your reply, Heiko

I don’t think that this is something on our end. Could you share more of your views? In the second case, it looks like you are forgetting to pattern match on %{"form" => params} in your handle event function.

Hi Zach…

I think, you got my question wrong.
Of course. I could pattern match on the ‘form param’.
But why do I have to?

Why don"t these two Ash-functions produce the same params?

Kind regards from Heiko

P.S.: Thiis isn’t a big thing and I really appreciate the superb working of the Ash Framework.

There’s a bit more involved than form structs submitting params - the params you get depends on the code in your view, which is why Zach asked to see it.

Hi Rebecca,

thank you for clarifying what you need.

defmodule TuneshgWeb.ArtistLive.FormComponent do
.....

@impl true
  def update(assigns, socket) do
    {:ok,
     socket
     |> assign(assigns)
     |> assign_form()}
  end
.....

defp assign_form(%{assigns: %{artist: artist}} = socket) do
    form =
      if artist do
        # Tuneshg.Music.form_to_update_artist(artist)

        # instead of
        # AshPhoenix.Form.for_update(artist, :update, as: "artist")

        # doesn't work. Different Params to Validate
        # HANDLE EVENT "validate" in TuneshgWeb.ArtistLive.Index
        # Component: TuneshgWeb.ArtistLive.FormComponent
        # Parameters: %{"_target" => ["form", "name"], "form" => %{"_unused_biography" => "", "_unused_name" => "", "biography" => "", "name" => "m"}}
        # Why does that happen?

        # when using
        # AshPhoenix.Form.for_update(artist, :update, as: "artist")
        # the params are:
        # HANDLE EVENT "validate" in TuneshgWeb.ArtistLive.Index
        # Component: TuneshgWeb.ArtistLive.FormComponent
        # Parameters: %{"_target" => ["artist", "biography"], "artist" => %{"biography" => "my_biography", "name" => "my_name"}}

        AshPhoenix.Form.for_update(artist, :update, as: "artist")
      else
        # Tuneshg.Music.form_to_create_artist()
        # doesn't work for the same reason

        AshPhoenix.Form.for_create(Tuneshg.Music.Artist, :create, as: "artist")
      end

    assign(socket, form: to_form(form))
  end
...

end

Without seeing the rest of your view, one of your forms specifies as: "artist" which is why it uses the artist key in the submitted params.

1 Like

Rebecca,

of course you are totally right.
I did change it and everything works perfectly now.
Thank you for your patience.

I may look dumb, but I saw as: “artist” in a former version and thought it was the right way of doing it.

Kind regards from Heiko