We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
Ecto changesets provide built-in validations like validate_required/2
and validate_length/3
, but sometimes you need custom validation logic. In this post, we'll explore how to implement custom validations in Ecto.
Let's say we have a User
schema, and we need to ensure that the age
field is at least 18.
We can define the schema like this and add a the custom validator validate_age
:
defmodule MyApp.Accounts.User do
use Ecto.Schema
import Ecto.Changeset
schema "users" do
field :name, :string
field :age, :integer
end
def changeset(user, attrs) do
user
|> cast(attrs, [:name, :age])
|> validate_required([:name, :age])
|> validate_age()
end
defp validate_age(changeset) do
validate_change(changeset, :age, fn :age, age ->
if age < 18 do
[{:age, "must be at least 18"}]
else
[]
end
end)
end
end
Another approach is to check the value directly and add an error manually:
defp validate_age(changeset) do
age = get_change(changeset, :age, get_field(changeset, :age))
if age && age < 18 do
add_error(changeset, :age, "must be at least 18")
else
changeset
end
end
When to use each approach:
validate_change/3
is useful for concise validations that return lists of errors.add_error/3
is better when checking multiple fields or requiring more control over the validation logic.
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts, subscribe use the RSS feed.