feat: attribute_in/2 builtin validation

This commit is contained in:
Zach Daniel 2023-04-28 16:05:58 -04:00
parent 7e517fc5d0
commit d7aaec7499
2 changed files with 62 additions and 0 deletions

View file

@ -0,0 +1,47 @@
defmodule Ash.Resource.Validation.AttributeIn do
@moduledoc false
@opt_schema [
attribute: [
type: :atom,
required: true,
doc: "The attribute to check"
],
list: [
type: :any,
required: true,
doc: "The list of values that the attribute must be in"
]
]
use Ash.Resource.Validation
alias Ash.Error.Changes.InvalidAttribute
@impl true
def init(opts) do
case Spark.OptionsHelpers.validate(opts, @opt_schema) do
{:ok, opts} ->
{:ok, opts}
{:error, error} ->
{:error, Exception.message(error)}
end
end
@impl true
def validate(changeset, opts) do
value = Ash.Changeset.get_attribute(changeset, opts[:attribute])
if value in opts[:list] do
:ok
else
{:error,
InvalidAttribute.exception(
value: value,
field: opts[:attribute],
message: "must equal %{value}",
vars: [field: opts[:attribute], value: opts[:value]]
)}
end
end
end

View file

@ -88,6 +88,21 @@ defmodule Ash.Resource.Validation.Builtins do
{Validation.AttributeEquals, attribute: attribute, value: value}
end
@doc """
Validates that an attribute is being changed to one of a set of specific values, or is in the the given list if it is not being changed.
## Examples
validate attribute_in(:state, [1, 2, 3])
# Or to only check for changing to a something in a given list
validate attribute_in(:state, [1, 2, 3]), where: [changing(:state)]
"""
@spec attribute_in(attribute :: atom, list :: [term]) :: Validation.ref()
def attribute_in(attribute, list) do
{Validation.AttributeIn, attribute: attribute, list: list}
end
@string_length_opts [
min: [
type: :non_neg_integer,