I have an update_changeset
in which I want to prevent nil
values from being written.
I tried adding a validate_change
def update_changeset(user, attrs) do
user
|> cast(attrs, [:full_name])
|> validate_change(:full_name, fn :full_name, full_name ->
if full_name == nil do
[full_name: "cannot be blank"]
else
[]
end
end)
end
But since it only gets called when a non-nil value is present, it still lets me write full_name: nil into the database.
How can I make this work?
Updated: here is how I implemented from help from fellows:
defp prevent_empty(changeset, fields) do
Enum.reduce(fields, changeset, fn field, changeset ->
value = get_field(changeset, field)
if value in ["", nil] do
add_error(changeset, field, "cannot be empty or blank")
else
changeset
end
end)
end
One has to handle it manually, with a help of Ecto.Changeset.add_error/4
.
def update_changeset(user, %{full_name: fn} = attrs) do
user
|> cast(attrs, [:full_name])
|> prevent_empty_full_name()
end
defp prevent_empty_full_name(%{changes: %{full_name: full_name}} = changeset)
when full_name in ["", nil],
do: add_error(changeset, :full_name, "empty")
defp prevent_empty_full_name(changeset),
do: changeset