Phoenix/Elixir - validate_format() failing for integer

Viewed 1496

In my Phoenix app, I am trying to use validate_format() on one of my changesets to make sure that an optional integer value is not negative, if it has been provided. However, I'm getting an error back when using the method, and I'm not sure what I'm doing wrong.

Here's my schema and changeset - since :duration is already defined as an integer, I'm really only concerned about making sure it does not include a minus sign:

embedded_schema do
  field :content, :string
  field :title, :string
  field :duration, :integer

  timestamps()
end

def changeset(struct, params \\ %{}) do
  struct
  |> cast(params, [:id, :content, :title, :duration])
  |> validate_length(:title, max: 99, message: "Title must be less than 100 characters.")
  |> validate_format(:duration, ~r/[^-]\d+/)
end

If I try to submit the value of -1, for instance, this returns the error:

** (FunctionClauseError) no function clause matching in Kernel.=~/2
    (elixir) lib/kernel.ex:1629: Kernel.=~(-1, ~r/[^-]\d+/)
    (ecto) lib/ecto/changeset.ex:1357: anonymous fn/5 in Ecto.Changeset.validate_format/4

and the same error occurs with valid values, as well.

I've used validate_format() previously on string fields and it has worked just fine - I can't tell what I'm doing wrong here. Can anyone clarify the right way to handle this function?

1 Answers

I believe validate_format is another use case. For your particular problem I would use validate_number For example:

def changeset(struct, params \\ %{}) do
  struct
  |> cast(params, [:id, :content, :title, :duration])
  |> validate_length(:title, max: 99, message: "Title must be less than 100 characters.")
  |> validate_number(:duration, greater_than: 0)
end
Related