Custom Phoenix Validations
Today I learned how to write a custom Phoenix model validation. It came from the Phoenix port of this very application, which requires that posts be 200 words or less.
Phoenix doesn't have a word length validation, so I had to make my own. Here it is, minus some irrelevant lines of code:
# web/models/post.ex
def changeset(struct, params \\ %{}) do
struct
|> cast(params, [:title, :body, :channel_id])
|> validate_length_of_body
end
defp validate_length_of_body(changeset) do
body = get_field(changeset, :body)
validate_length_of_body(changeset, body)
end
defp validate_length_of_body(changeset, body) do
if length(String.split(body, ~r/\s+/)) > 200 do
add_error(changeset, :body, "should be at most 200 word(s)")
else
changeset
end
end
When the post body is greater than 200 words (as defined by splitting on whitespace characters), the validation adds an error to the body
field that mimics the errors Phoenix provides for character-length validation failures. Including the (s)
, which I kind of like.
When the body is short enough, changeset
is returned from the function of the same name, a form of success.
Pattern matching FTW.
Tweet