Erabi.Changeset (Erabi v0.1.0)

Copy Markdown View Source

The rules of a picker (Erabi.Rules), checked on the server, in an Ecto.Changeset.

def changeset(task, params) do
  task
  |> cast(params, [:status, :labels])
  |> Erabi.Changeset.validate_choice(:status, [required: true], options: Task.statuses())
  |> Erabi.Changeset.validate_choice(:labels, @label_rules, options: &Labels.existing/1)
end

It checks the field's value after the cast (an atom of an Ecto.Enum, an integer id, a list for {:array, _}), as the form posted it, and adds at most one error. The error has validation: :erabi and kind: (the reason, see Erabi.Rules.error/0) with what the message needs (count, value...), so that translate_error/1 of a Phoenix app can translate it.

Options:

  • :options - the options the value must be among (unless the rules have create: true): anything a picker takes, or a function of the posted values (texts) that gives the ones that exist, for options that come from a search (&Labels.existing/1 with a query of where: l.name in ^values). Without it, any value is an option.
  • :message - a message for every error, or a map of messages by kind (%{too_many: "three labels at most"}).

Summary

Functions

The default error messages, by kind. They follow Ecto's own, so that an app's Gettext already has most of them.

Checks the value of a field against the rules (an Erabi.Rules or its options) and the options. See the moduledoc.

Functions

messages()

@spec messages() :: %{required(atom()) => String.t()}

The default error messages, by kind. They follow Ecto's own, so that an app's Gettext already has most of them.

iex> Erabi.Changeset.messages().required
"can't be blank"

validate_choice(changeset, field, rules, opts \\ [])

@spec validate_choice(
  Ecto.Changeset.t(),
  atom(),
  Erabi.Rules.t() | keyword(),
  keyword()
) ::
  Ecto.Changeset.t()

Checks the value of a field against the rules (an Erabi.Rules or its options) and the options. See the moduledoc.

iex> types = %{labels: {:array, :string}}
iex> changeset =
...>   {%{}, types}
...>   |> Ecto.Changeset.cast(%{labels: ["bug", "wontfix"]}, [:labels])
...>   |> Erabi.Changeset.validate_choice(:labels, [max: 3], options: ["bug", "feature"])
iex> changeset.errors
[labels: {"is not one of the options", [validation: :erabi, kind: :not_allowed, value: "wontfix"]}]