Validating changesets in Ecto can be really simple. We previously wrote about using validate_change/3
to validate changesets here:
While working through other custom validations, we came across another straightforward method of validating changesets. We can write a function that takes a changeset and returns it if valid and fits our requirements, or returns the changeset with errors added.
In our previous example, we covered validating that the url
string field was in a specific AWS bucket. Here is another version of that example here:
@url "https://s3.amazonaws.com/our-bucket"
defp validate_url_format(changeset, field) do
case changeset.valid? do
true ->
url = get_field(changeset, field)
case String.starts_with?(field, @url) do
true -> changeset
_ -> add_error(changeset, :url, "Format invalid")
end
_ ->
changeset
end
end
We then pass this function to our changeset:
def changeset(struct, params \\ %{}) do
struct
|> cast(params, [:url])
|> validate_required([:url])
|> unique_constraint(:url)
|> validate_url_format(:url)
end
We can write a couple quick tests to test that this works as well:
test "changeset with valid url format" do
good_url = "https://s3.amazonaws.com/our-bucket/happy-cow.jpg"
changeset = Photo.changeset(%Photo{url: good_url})
assert changeset.valid?
end
test "changeset with invalid url format" do
bad_url = "https://s3.amazonaws.com/other-bucket/happy-lamb.jpg"
changeset = Photo.changeset(%Photo{url: bad_url})
refute changeset.valid?
end
That’s it!
Get notified of any new episodes as we release them.