Server-side params for AshPhoenix Form
Sometimes I will have an AshPhoenix form to create or update a resource, and I want some of the fields to be provided from the server and not set or visible on the client. Sometimes these are coming from uploads, other times it's computed from other state.
What is the best way to provide this data to
validate
and submit
? So far I've been defining a form_params(socket, params)
helper that injects/overrides various params before passing the result to validate/submit. This has worked OK but feels wrong, and today I ran into an issue of having to reverse-engineer how AshPhoenix expects unions to work.
Appreciate any insight and guidance y'all can provide!8 Replies
Have you tried using the
params/prepare_params
option for the for_*
functions https://hexdocs.pm/ash_phoenix/AshPhoenix.Form.html#for_action/3I don't think
params
would work as the values aren't known at the time mount
is called (they are dependent on user actions/input). And prepare_params
seems to only get the params as input, so it wouldn't be able to merge in outside data from the socket assigns?In that case, I think having a helper function like you did is totally valid
or more like in general, not just this specific case
Appreciate it. I got worried because I felt I had to do some weird things when passing in union types to params and wondered if there was some other way to pass data in that made more sense. If there isn't then I'm happy to keep down this path!
what exactly felt wierd about unions?
And I didn't see anything in the docs regarding this topic so didn't know if it was an expected way to go about it
yeah, I think a lot of people think there is an Ash way for all of the things, but in the end it's all just functions anyway.
Doesn't mean we can't make it more ergonomic if the need arises though.
One of my resources has a field of type
{:array, :union}
with storage: :map_with_tag
and each type being a TypedStruct with tag: "type"
and tag_value
being some string. I expected to be able to pass in a list of maps with the type
field set appropriately, but instead i had to convert them to a map of idx => %{"_union_type" => type, "value" => data}
with a function kind of like this
I think this is because under the hood Ash is building a bunch of nested forms which expect this input. It wouldn't have been a problem if I was getting the union data from the client, but because I'm passing it in directly it went against Ash's expectations.