Hi all,
is there any helper to perform Ecto.Changeset.validate_format/4
for every element in an Array field in Ecto, or should I write my own?
Thank you
Hi all,
is there any helper to perform Ecto.Changeset.validate_format/4
for every element in an Array field in Ecto, or should I write my own?
Thank you
In the end I made something like:
def valid_format_array?(changeset, field, regex) do
case
Ecto.Changeset.get_field(changeset, field)
|> Enum.all?(fn value -> String.match?(value, regex) end)
do
true -> changeset
false -> Ecto.Changeset.add_error(changeset, field, "has invalid format")
end
end
Thank you
If you wanted to capture the each individual invalid value in the array, you could swap Enum.all?
for Enum.reduce
instead and use the changeset as an accumulator.
def validate_array_field(changeset, field, regex) do
Enum.reduce(Ecto.Changeset.get_field(changeset, field), changeset, fn value ->
case String.match?(value, regex) do
true -> changeset
false -> Ecto.Changeset.add_error(changeset, field, "has invalid format: #{value}")
end
end)
end
Make sense! thank you
Also, just realized that I didn’t specify the accumulator above so it should have something like this instead.
def validate_array_field(changeset, field, regex) do
Enum.reduce(Ecto.Changeset.get_field(changeset, field), changeset, fn value, acc ->
case String.match?(value, regex) do
true -> acc
false -> acc = Ecto.Changeset.add_error(acc, field, "has invalid format: #{value}")
end
end)
end
And if you wanted to use Ecto.Changeset.validate_change
that @dimitarvp had mentioned, the accumulator would need to be changed from a changeset to a list.
changeset = Ecto.Changeset.validate_change(changeset, :field, fn :field, field ->
Enum.reduce(Ecto.Changeset.get_field(changeset, field), [], fn value, acc ->
case String.match?(value, regex) do
true -> acc
false -> [{field, "has invalid format: #{value}"}, acc]
end
end)
end)
yeah I did that in my version of your previously proposed code