diff --git a/lib/ash_phoenix/form/auto.ex b/lib/ash_phoenix/form/auto.ex index 22060e9..30ac127 100644 --- a/lib/ash_phoenix/form/auto.ex +++ b/lib/ash_phoenix/form/auto.ex @@ -46,7 +46,7 @@ defmodule AshPhoenix.Form.Auto do However, you may also want to include the relevant fields for the update that would subsequently occur. To that end, a special nested form called `:_update` is created, that uses an empty instance of that resource as the base of its changeset. This may require some manual manipulation of that data before rendering the relevant form because it assumes all the default values. To solve for this, - if you are using liveview, you could actually look up the record using the input from the read action, and then use `AshPhoenix.update_form/3` + if you are using liveview, you could actually look up the record using the input from the read action, and then use `AshPhoenix.Form.update_form/3` to set that looked up record as the data of the `_update` form. ### Many to Many Relationshisp diff --git a/lib/ash_phoenix/form/form.ex b/lib/ash_phoenix/form/form.ex index 5ee2599..9f63938 100644 --- a/lib/ash_phoenix/form/form.ex +++ b/lib/ash_phoenix/form/form.ex @@ -601,7 +601,26 @@ defmodule AshPhoenix.Form do ], params: [ type: :any, - doc: "Override the params used for submit. Defaults to `AshPhoenix.Form.params(form)`" + doc: """ + If specified, `validate/3` is called with the new params before submitting the form. + + This is a shortcut to avoid needing to explicitly validate before every submit. + + For example: + + ```elixir + form + |> AshPhoenix.Form.validate(params) + |> AshPhoenix.Form.submit(Api) + ``` + + Is the same as: + + ```elixir + form + |> AshPhoenix.Form.submit(Api, params: params) + ``` + """ ], before_submit: [ type: {:fun, 1}, @@ -626,6 +645,17 @@ defmodule AshPhoenix.Form do @spec submit(t(), Ash.Api.t(), Keyword.t()) :: {:ok, Ash.Resource.record()} | :ok | {:error, t()} def submit(form, api, opts \\ []) do + form = + if opts[:params] do + AshPhoenix.Form.validate( + form, + opts[:params], + Keyword.take(opts, Keyword.keys(@validate_opts)) + ) + else + form + end + opts = validate_opts_with_extra_keys(opts, @submit_opts) changeset_opts = Keyword.drop(form.opts, [:forms, :errors, :id, :method, :for, :as]) before_submit = opts[:before_submit] || (& &1) @@ -639,7 +669,7 @@ defmodule AshPhoenix.Form do form.resource |> Ash.Changeset.for_create( form.source.action.name, - opts[:params] || params(form), + params(form), changeset_opts ) |> before_submit.() @@ -649,7 +679,7 @@ defmodule AshPhoenix.Form do form.data |> Ash.Changeset.for_update( form.source.action.name, - opts[:params] || params(form), + params(form), changeset_opts ) |> before_submit.() @@ -659,7 +689,7 @@ defmodule AshPhoenix.Form do form.data |> Ash.Changeset.for_destroy( form.source.action.name, - opts[:params] || params(form), + params(form), changeset_opts ) |> before_submit.() @@ -669,7 +699,7 @@ defmodule AshPhoenix.Form do form.resource |> Ash.Query.for_read( form.source.action.name, - opts[:params] || params(form), + params(form), changeset_opts ) |> before_submit.() @@ -846,6 +876,22 @@ defmodule AshPhoenix.Form do end end + @doc """ + Sets the data of the form, in addition to the data of the underlying source, if applicable. + + Queries do not track data (because that wouldn't make sense), so this will not update the data + for read actions + """ + def set_data(form, data) do + case form.source do + %Ash.Changeset{} = source -> + %{form | data: data, source: %{source | data: data}} + + %Ash.Query{} -> + %{form | data: data} + end + end + @doc """ Returns the parameters from the form that would be submitted to the action. diff --git a/test/form_test.exs b/test/form_test.exs index 9a9810f..5fad786 100644 --- a/test/form_test.exs +++ b/test/form_test.exs @@ -77,8 +77,7 @@ defmodule AshPhoenix.FormTest do ] ) |> Form.add_form(:post, params: %{}) - |> Form.validate(%{"text" => "text", "post" => %{}}) - |> Form.submit(Api) + |> Form.submit(Api, params: %{"text" => "text", "post" => %{}}) |> elem(1) |> form_for("action")