Changeset validation firing incorrectly?

Hi,

I am working through the Pragmatic Programmer Phoenix course, and Ch 13 - Form Create, we are asked to add realtime validations to the form field. The form has a few fields related to a server, like name, status, etc.
The name field has two constraints, that it not be blank and that its length falls between a certain min and max. The problem I am having is that the first constraint is firing incorrectly, i.e. validate_required(:name), so if I type a single character in the name field, it should not fire the required field and instead the validate_length should be the one that fires, because it is non-empty and not long enough.

Here is my changeset definition:

def changeset(server, attrs) do
    server
    |> cast(attrs, [
      :name,
      :status,
      :deploy_count,
      :size,
      :framework,
      :git_repo,
      :last_commit_id,
      :last_commit_message
    ])
    |> validate_required([
      :name,
      :status,
      :deploy_count,
      :size,
      :framework,
      :git_repo,
    ])
    |> validate_length(:name, min: 2, max: 200, message: "Must be at least 2 characters")
  end

My debug statements showing the character coming in from the form and then the validation:

Validating
%{
  "_csrf_token" => "NA8hcXcAFj8QAhkra18ALkpdNg4ldxcVMBhDESsLf0ut_8QA28DTuNgd",
  "_target" => ["server", "name"],
  "server" => %{"deploy_count" => "", "framework" => "", "name" => "d"}
}
#Ecto.Changeset<
  action: :insert,
  changes: %{},
  errors: [
    name: {"can't be blank", [validation: :required]},
    status: {"can't be blank", [validation: :required]},
    deploy_count: {"can't be blank", [validation: :required]},
    size: {"can't be blank", [validation: :required]},
    framework: {"can't be blank", [validation: :required]},
    git_repo: {"can't be blank", [validation: :required]}
  ],
  data: #LiveViewStudio.Servers.Server<>,
  valid?: false

So my question is why is the required validation going off when it clearly is receiving a character, and further preventing the correct validation from being activated?
Thanks for any pointers on how I can go deeper to find the issue or if there is something else I am doing wrong.

The changes: %{} in the changeset output suggest that the character from the input is not making it to the changeset. Can you post the code that’s calling this function?

Hi, thanks for taking a look. Here is the code, which is identical to a different form that does work:

def handle_event("validate", params, socket) do
    IO.puts("Validating")
    IO.inspect(params)
    cs = %Server{}
      |>  Servers.change_server(params)
      |>  Map.put(:action, :insert)

    IO.inspect cs
    socket = assign(socket, changeset: cs)
    {:noreply, socket}
  end

And the EEX fragment:

 <%= f = form_for @changeset, "#" , phx_submit: "save", phx_change: "validate"%>
            <div class="field">
                <%= label f, :name %>
                <%= text_input f, :name, autocomplete: :off %>
                <%= error_tag f, :name %>
            </div>

Maybe you want pass params["server"] instead only params to Servers.change_server function.

3 Likes

That dit it, thanks SO much!