Setting defaults for a form input that is an argument and not an attribute?

rgraff
2023-07-14

rgraff:

I have an update action that takes an argument. In the form for this action, I need to set the default value for the form input. The default value is dependent on the current state of the resource being updated.

I explored using the default option for an action argument; however, It accepts a zero-argument function, so there’s no way to get the resource being updated.

I explored using the prepare_params option for AshPhoenix.Form.for_update but I couldn’t find any examples. It’s arrity 2 and receives the params but is only called when the form is validated or submitted.

Side quest(ion): what’s the difference between prepare_params and transform_params if they’re both called only on validate and submit?

zachdaniel:

IIRC prepare_params is pre-validate

zachdaniel:

and transform_params is post validate

zachdaniel:

oh, no thats wrong

zachdaniel:

transform_params is passed to child forms

zachdaniel:

so all params on all forms go through it

rgraff:

How can I set the params before I render the form?

zachdaniel:

you could validate it once w/ your own params

rgraff:

Just saw prepare_source, trying to figure out how that works.

zachdaniel:

so, lets revisit the initial use case though

zachdaniel:

if you have a default value that is based on the current state of things, you can do that with a change on the action as well

zachdaniel:

change fn changeset, _ -> 
  if changeset.arguments[:foo] do
    changeset
  else
    Ash.Changset.set_argument(changeset, :foo, changeset.data.bar)
  end
end

zachdaniel:

(for example)

zachdaniel:

changes run when we validate the form (which is why anything w/ side effects goes in before/after action hooks)

rgraff:

ok, so I can create my input form and then immediately validate it to get the argument set?

rgraff:

I got it working with prepare_source .

              AshPhoenix.Form.for_update(plan, :update,
                api: Environments,
                prepare_source: fn changeset ->
                  Ash.Changeset.set_argument(
                    changeset,
                    :feature_keys,
                    default_feature_keys(changeset.data)
                  )
                end
              )

I like this a little better because the defaults are more related to the form than the action.

rgraff:

Made a few doc changes. Hopefully, my understanding is correct. https://github.com/ash-project/ash_phoenix/pull/97/files