Skip to content

Validating data with ecto changesets and no database

Joel Meador edited this page Jun 8, 2026 · 1 revision

I would like to validate some user input that doesn't directly map to a database column and would like to be able to use the validation's output as if it were a normal database-backed model. How do I do that?

Ecto.Changesets require just three things to validate data:

If you wanted to verify a number input by a user was say a number and above 5, you might write something like the following to check that value:

# some controller
def verify(conn, params) do
  case SomeContext.verify_enough(params) do
    {:ok, value} ->
      conn
      |> put_status(200)
      |> assign(:value, value)
      |> render("show.json")

    {:error, changeset} ->
      conn
      |> put_status(422)
      |> assign(:changeset, changeset)
      |> put_view(Web.ErrorView)
      |> render("changeset.json")
  end
end

# some context
def verify_enough(params) do
  case SomeEctoModel.validate_high_enough_value(params) do
    {:ok, data} ->
      data.value

    {:error, changeset} ->
      {:error, changeset}
  end
end

# some ecto model
def validate_high_enough_value(params) do
  types = %{value: :integer}

  {%{}, types}
  |> cast(params, Map.keys(types))
  |> validate_required([:value])
  |> validate_number(:value, greater_than: 5)
  |> apply_action(:validate)
end

This is as simple as you can get, but you can imagine integrating this changeset into a larger one that may save something to the database if that's necessary. The important thing is you are validating type and value of user input without having to write one-off methods to do so, but instead of using familiar machinery from Ecto.

Home

TODO: can we recreate the tag system here roughly with sections about certain subjects?

Clone this wiki locally