I see this in a lot of function calls in Elixir / Phoenix controllers, but just am not sure what I am looking at exactly. I assume its a pattern match of some kind, but don’t see how or why the string “user” is involved and what it is doing exactly.
Example: (This is from generated 1.6 authentication code I believe)
def create(conn, %{"user" => user_params}) do
case Accounts.register_user(user_params) do
(try and register the user)
end
end
Since all I see in router.ex is this black magic, I can’t tell how the function is getting called.
post "/users/register", UserRegistrationController, :create
And I also don’t see anything called “user” in the heex template. (will post if needed)
You can take a look at your form and find any input name. It would be something like name="user[email]". That when translataded into a map for phoenix would be %{“user” => %{“email” => “value”}`.
What makes it being encapsulated? When you use any phoenix form helper such as form_for or <.form> you pass a for struct or atom name. If it’s an atom it’s going to encapsulate under that name, if it’s a ModelName it’s going to make a camel case model_name version for it.
When you submit the form, phoenix sends that action the payload as a Map so that’s why you see that format and the pattern matching on the function params is just phoenix telling “this is what I expect, if it’s something else I know it’s not going to work”
As also explained by @lubien, the hierarchy of the maps your controllers receive from Phoenix is well-defined and can be easily found in the docs. But long story short, having this in your HTML:
<input type="checkbox" name="marketing[consent]">
…will lead to Phoenix giving you this as an argument to your controller’s function:
Thanks for the explanation - that makes a lot of sense.
You can take a look at your form and find any input name. It would be something like name="user[email]"
I can’t find anything like that in my registration form, but this is old code that I am looking through and it’s possible I changed it (and broke it), and if so you just helped me fix it, which I definitely appreciate. Here is what my form looks like:
To add to what @patrickdm said, the for={@changeset} is how it figures out what to call the map key (It’s a changeset for a User so it creates a "user" key).