Name Your Ecto Validations

elixir ecto
Posted on: 2022-12-07

(Published via time machine. Just kidding, my blog publication tooling was broken and it took me a long time to get around to fixing it.)

When Ecto.Changeset.validate_required/3 fails, the error it adds includes not only a message but also the information [validation: :required].

This means that in tests, you can assert which validation failed and not the words in the validation message.

assert {_msg, [validation: :required]} =
  changeset.errors[:name]

If you write a custom Ecto validation, your add_error/4 call can do the same.

add_error(
  changeset,
  :ketchup,
  "insufficiently fancy",
  validation: :not_fancy
)

...and in the test:

assert {_msg, [validation: :not_fancy]} =
  changeset.errors[:ketchup]

If you do this, you can modify the human-readable message without breaking tests which simply assert whether it passed.