How to Write Custom Validations for Ecto Changesets
Written for Phoenix 1.5.7 & Ecto 3.5.5
Ecto's changesets provide common validation options but you can also write your own. Below we have a basic module with a schema and changeset
function for our tutorials
table:
defmodule MyApp.Tutorials.Tutorial do
use Ecto.Schema
import Ecto.Changeset
schema "tutorials" do
field :name, :string
field :is_useful, :boolean
timestamps()
end
@doc false
def changeset(tutorial, attrs) do
tutorial
|> cast(attrs, [:name, :is_useful])
|> validate_required([:name, :is_useful])
end
end
To add a custom validation, we'll first write the logic:
defmodule MyApp.Tutorials.Tutorial do
# ...
def validate_something(changeset) do
case your_logic do
true ->
# Continue
changeset
false ->
# Add an error to the changeset
add_error(changeset, :some_key, "displayed error message")
end
end
end
Then we'll add the custom validation of the changeset function:
defmodule MyApp.Tutorials.Tutorial do
# ...
@doc false
def changeset(tutorial, attrs) do
tutorial
|> cast(attrs, [:name, :is_useful])
|> validate_required([:name, :is_useful])
|> validate_something()
end
# ...
end
That's all there is to it! For further reading, check out the documentation for add_error
and the default validation options that Ecto's changesets provide.