Hello. I’m having some trouble getting errors to render inside a nested form.
I have the following:
<%= form_for @changeset, signup_path(@conn, :create), fn f -> %>
<%= hidden_input f, :plan, value: @plan %>
<%= hidden_input f, :channel, id: "channel" %>
<%= inputs_for f, :owner, fn u -> %>
<%= text_input u, :email, class: "form-control", required: true, readonly: true, style: "background-color:#f2f2f2" %>
<%= label u, "Email (you can change this later)" %>
<%= error_tag u, :email %>
<%= text_input u, :first_name, autofocus: true, class: "form-control", required: true %>
<%= label u, :first_name %>
<%= error_tag u, :first_name %>
<%= text_input u, :last_name, class: "form-control", required: true %>
<%= label u, :last_name %>
<%= error_tag u, :last_name %>
<%= password_input u, :password, class: "form-control", pattern: ".{8,}", title: "Password must have 8 or more characters.", required: true %>
<%= label u, "Password (minimum 8 characters)" %>
<%= error_tag u, :password %>
<%= password_input u, :password_confirmation, class: "form-control", required: true %>
<%= label u, :password_confirmation %>
<%= error_tag u, :password_confirmation %>
<% end %>
<%= text_input f, :name, class: "form-control", required: true %>
<%= label f, :organization_name %>
<%= error_tag f, :name %>
<%= submit "Finish", class: "btn btn-block btn-lg" %>
<% end %>
Pretty straightforward. There is an organization
parent entity, and it has an owner
child entity. When the user is creating their account, I allow them to enter info about both, and create and associate them behind the scenes.
The “happy path” works. But when the changeset is invalid, the errors don’t get rendered on the form. Below is an example changeset where the user did not enter their password confirmation correctly:
#Ecto.Changeset<
action: nil,
changes: %{
name: "testtest",
owner: #Ecto.Changeset<
action: :insert,
changes: %{
email: "someemail@fastmail.com",
first_name: "sdf",
last_name: "asdf",
password: "testtest",
password_confirmation: "testtest1"
},
errors: [
password_confirmation: {"does not match password",
[validation: :confirmation]}
],
data: #MyApp.Accounts.User<>,
valid?: false
>
},
errors: [],
data: #MyApp.Organizations.Organization<>,
valid?: false
>
The controller action’s relevant portion:
{:error, _operation, changeset, _changes} ->
conn
|> put_status(:unprocessable_entity)
|> put_flash(:error, "Hmm, that didn't work. Please see the errors below.")
|> render("create_account.html", plan: plan.description, changeset: changeset, channel: channel, title: "MyApp | Create Account")
What is missing here?
The changeset appears to be structured correctly, in the sense that organization
is the parent entity and owner
is the child entity. This mirrors the structure of the form. So, shouldn’t the error_tag
corresponding to the Password Confirmation field render that field’s error?