Domo.Changeset (Domo v1.3.4) View Source

Validation functions for Echo.Changeset.

The Ecto schema changes can be validated to conform to types in t() and to fulfill appropriate preconditions.

defmodule User do
  use Ecto.Schema
  use Domo, ensure_struct_defaults: false

  import Ecto.Changeset
  import Domo.Changeset

  schema "users" do
    field :first_name, :string
    field :last_name, :string
    field :age, :integer
  end

  @type t :: %__MODULE__{
    first_name :: String.t() | nil,
    last_name :: String.t(),
    age :: age()
  }

  @type age :: pos_integer()
  precond age: &validate_age/1

  @max_age 150
  defp validate_age(age) when age < @max_age, do: :ok
  defp validate_age(_age), do: {:error, "age should be in 1..#{@max_age}"}

  def changeset(user, attrs) do
    user
    |> cast(attrs, typed_fields())
    |> validate_required(required_fields())
    |> validate_type(maybe_filter_precond_errors: true)
  end
end

The ensure_struct_defaults: false option disables the validation of defaults to match to t() type at compile time. That is useful because any Ecto schema has all fields set to nil by default.

typed_fields/1 and required_fields/1 are added automatically to the current module by using Domo.

The first_name field is not required to have a value in the changeset because it has nil as one of the possible types defined.

validate_type/2 function automatically adds type ensurance errors to the changeset. The maybe_filter_precond_errors: true option enables the filtering of the precondition error message for :age field. That error is ready to be communicated to the user.

Link to this section Summary

Functions

Validates schemaless changeset changes to conform to the schema's t() type and fulfill preconditions.

Validates changeset changes to conform to the schema's t() type and fulfill preconditions.

Link to this section Functions

Link to this function

validate_schemaless_type(changeset, struct, opts \\ [])

View Source

Validates schemaless changeset changes to conform to the schema's t() type and fulfill preconditions.

Similar to validate_type/2.

struct is a module name providing t() type and preconditions for changes validation.

Examples

{%{}, %{first_name: :string, last_name: :string, age: :integer}}
|> cast(%{last_name: "Doe", age: 21}, [:last_name, :age])
|> validate_schemaless_type(User)
Link to this function

validate_type(changeset, opts \\ [])

View Source

Validates changeset changes to conform to the schema's t() type and fulfill preconditions.

The function performs validations within the call to Ecto's validate_change/3. In case there's at least one error, the list of errors will be appended to the :errors field of the changeset and the :valid? flag will be set to false.

The function raises a RuntimeError if some of the changed fields are not defined in the t() type.

Options

  • :fields - the list of changed fields that should be validated
  • :maybe_filter_precond_errors - when set to true the function returns first error received from the precondition function for each field. In case if no precondition function is defined for the field type, then autogenerated error will be returned.
  • :take_error_fun - function returning most relevant error from the list of errors for a field. Works when maybe_filter_precond_errors: true is given. It can be useful in cases when several precondition errors are returned for the given field. By default it's fn list -> List.first(list) end.

Examples

%User{}
|> cast(%{last_name: "Doe", age: 21}, [:last_name, :age])
|> validate_type()