Hello everyone!
I’m working with some validation when creating an object. I receive some attributes and I’m using them to create a location
. Attributes is something like:
attrs = %{latitude: 123.2, longitude: 123.4, metadata: %{timestamp: "2015-05-05T01:31:54", accuracy: 1}}
To create I use:
location
|> cast(attrs, [:latitude, :longitude, :metadata])
|> validate_required([:latitude, :longitude])
Is there a way I can validate required for metadata.timestamp?
Sorry if something is wrong there, I started working with Elixir this week.
Thanks!
Hello and welcome to the forum.
It looks your metadata field is a map field, or jsonb.
You might have some solutions, each with their own dis/advantages.
On simple solution could be to have a custom validation.
Another one would be to embed metadata. The document (2015) has been updated in 2019…
2 Likes
An example of custom validation (not tested)
defp validate_field_contains_timestamp(changeset, field) when is_atom(field) do
validate_change(changeset, field, fn
(current_field, value) when is_map(value) ->
case Map.fetch(value, :timestamp) do
{:ok, _} -> []
:error -> [{current_field, "This field must have a timestamp"}]
end
(current_field, _) -> [{current_field, "This field must be a map"}]
end)
end
Then
location
|> cast(attrs, [:latitude, :longitude, :metadata])
|> validate_field_contains_timestamp(:metadata)
|> validate_required([:latitude, :longitude])
5 Likes
Thank you @kokolegorille! Your answer helped me validating it. It worked!