Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Phoenix.HTML.Form does not take errors from changeset

I have template code that looks like this:

<%= form_for @changeset, @action, fn f -> %>
  <%= if Enum.any?(f.errors) do %>
    <%= for {attr, message} <- f.errors do %>
      <li><%= humanize(attr) %> <%= message %></li>
    <% end %>
  <% end %>
<% end %>

But no errors are printed even if the changeset contains errors. Here is the inspected form struct. Notice that the errors list is empty even though it was built from the changeset with errors.

%Phoenix.HTML.Form{data: %BlogPhoenix.Comment{__meta__: #Ecto.Schema.Metadata<:built, "comments">,
  content: nil, id: nil, inserted_at: nil, name: nil, post_id: nil,
  posts: #Ecto.Association.NotLoaded<association :posts is not loaded>,
  updated_at: nil}, errors: [], hidden: [], id: "comment",
 impl: Phoenix.HTML.FormData.Ecto.Changeset, index: nil, name: "comment",
 options: [method: "post"],
 params: %{"content" => nil, "name" => nil, "post_id" => "1"},
 source: #Ecto.Changeset<action: nil, changes: %{},
  errors: [name: {"can't be blank", [validation: :required]},
   content: {"can't be blank", [validation: :required]}],
  data: #BlogPhoenix.Comment<>, valid?: false>}

What is going on here? Shouldn't this errors list be populated?

like image 211
Sam Avatar asked Apr 17 '17 13:04

Sam


1 Answers

Your changeset's :action is nil, which is what hides the errors (see source).

The Ecto.Changeset docs (under the "Changeset actions" headline) states:

For example, frameworks such as Phoenix uses the value of changeset.action to decide if errors should be shown or not on a given form.

The docs above suggest this approach:

changeset = User.changeset(%User{}, %{age: 42, email: "[email protected]"})

# Since we don't plan to call Repo.insert/2 or similar, we
# need to mimic part of its behaviour, which is to check if
# the changeset is valid and set its action accordingly if not.
if changeset.valid? do
  ... success case ...
else
  changeset = %{changeset | action: :insert} # action can be anything
  ... failure case ...
end
like image 138
Alvin Lindstam Avatar answered Sep 28 '22 02:09

Alvin Lindstam