This simple module gives a counter-intuitive result:
defmodule D do
import Ecto.Changeset
use Ecto.Schema
schema "ds" do
field :title, :string
end
def changeset(cs, t) do
cast(cs, %{"title" => t}, [:title])
|> validate_required([:title])
|> validate_length(:title, min: 10)
end
end
As expected, providing a short title triggers a validation error:
iex(1)> cs = D.changeset(%D{}, "foo")
If the user attempts to correct that but provides another short title, the changeset now has two validations errors on the same key:
iex(2)> cs = D.changeset(cs, "too short")
#Ecto.Changeset<
action: nil,
changes: %{title: "too short"},
errors: [
title: {"should be at least %{count} character(s)",
[count: 10, validation: :length, kind: :min, type: :string]},
title: {"should be at least %{count} character(s)",
[count: 10, validation: :length, kind: :min, type: :string]}
],
data: #D<>,
valid?: false
>
Where it gets counter-intuitive is that trying once again with a long-enough title, reduces the error count, but keeps one:
iex(3)> cs = D.changeset(cs, "now long enough")
#Ecto.Changeset<
action: nil,
changes: %{title: "now long enough"},
errors: [
title: {"should be at least %{count} character(s)",
[count: 10, validation: :length, kind: :min, type: :string]}
],
data: #D<>,
valid?: false
>
After that, no matter what title is given, the error count either goes back to 2 (if the title is too short), or goes to 1 (if the title is long enough) but the changeset never becomes valid?
despite being valid. What went wrong in that code?