# `Ash.Resource.Validation.Builtins`
[🔗](https://github.com/ash-project/ash/blob/v3.23.1/lib/ash/resource/validation/builtins.ex#L5)

Built in validations that are available to all resources

The functions in this module are imported by default in the validations section.

# `absent`

```elixir
@spec absent(attributes_or_arguments :: atom() | [atom()], opts :: Keyword.t()) ::
  Ash.Resource.Validation.ref()
```

Validates that the given attribute or argument or list of attributes or arguments are `nil`.

This is the inverse of `present/2`.

Use options to specify how many must be `nil`. If no options are provided, validates that they are all absent.

Keep in mind that some types cast certain values to `nil`, and validations are
applied after all inputs have been cast. For example, a `:string` type attribute
with the default constraints will cast `""` as `nil`, meaning an input of
`""` would pass the `absent` validation.

## Options

* `:at_least` (`t:non_neg_integer/0`) - At least this many must be absent. Defaults to the number of attributes provided

* `:at_most` (`t:non_neg_integer/0`) - At most this many must be absent. Defaults to the number of attributes provided

* `:exactly` (`t:non_neg_integer/0`) - Exactly this many must be absent

## Examples

    validate absent(:unsettable_option)

    validate absent([:first_name, :last_name]), where: [present(:full_name)]

    validate absent([:is_admin, :is_normal_user], at_least: 1)

# `action_is`

```elixir
@spec action_is(action :: atom() | [atom()]) :: Ash.Resource.Validation.ref()
```

Validates that the action name matches the provided action name or names. Primarily meant for use in `where`.

## Examples

    validate present(:foo), where: [action_is(:bar)]

    validate present(:foo), where: action_is([:bar, :baz])

# `any`

```elixir
@spec any(validations :: [Ash.Resource.Validation.ref()]) ::
  Ash.Resource.Validation.ref()
```

Validates that at least one of the provided validations passes

## Examples

    validate any([
      one_of(:status, [:valid]),
      match(:title, "^[a-z]+$")
    ])

# `argument_does_not_equal`

```elixir
@spec argument_does_not_equal(argument :: atom(), value :: term()) ::
  Ash.Resource.Validation.ref()
```

Validates that an argument is not being changed to a specific value, or does not equal the given value if it is not being changed.

## Examples

    validate argument_does_not_equal(:admin, true)

    # Or to only check for changing to a given value
    validate argument_does_not_equal(:admin, true), where: [changing(:admin)]

# `argument_equals`

```elixir
@spec argument_equals(argument :: atom(), value :: term()) ::
  Ash.Resource.Validation.ref()
```

Validates that an argument is being changed to a specific value, or equals the given value if it is not being changed.

## Examples

    validate argument_equals(:admin, true)

    # Or to only check for changing to a given value
    validate argument_equals(:admin, true), where: [changing(:admin)]

# `argument_in`

```elixir
@spec argument_in(argument :: atom(), list :: [term()]) ::
  Ash.Resource.Validation.ref()
```

Validates that an argument 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 argument_in(:state, [1, 2, 3])

    # Or to only check for changing to a something in a given list
    validate argument_in(:state, [1, 2, 3]), where: [changing(:state)]

# `attribute_does_not_equal`

```elixir
@spec attribute_does_not_equal(attribute :: atom(), value :: term()) ::
  Ash.Resource.Validation.ref()
```

Validates that an attribute is not being changed to a specific value, or does not equal the given value if it is not being changed.

## Examples

    validate attribute_does_not_equal(:admin, true)

    # Or to only check for changing to a given value
    validate attribute_does_not_equal(:admin, true), where: [changing(:admin)]

# `attribute_equals`

```elixir
@spec attribute_equals(attribute :: atom(), value :: term()) ::
  Ash.Resource.Validation.ref()
```

Validates that an attribute is being changed to a specific value, or equals the given value if it is not being changed.

## Examples

    validate attribute_equals(:admin, true)

    # Or to only check for changing to a given value
    validate attribute_equals(:admin, true), where: [changing(:admin)]

# `attribute_in`

```elixir
@spec attribute_in(attribute :: atom(), list :: [term()]) ::
  Ash.Resource.Validation.ref()
```

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)]

# `attributes_absent`

```elixir
@spec attributes_absent(attributes :: atom() | [atom()], opts :: Keyword.t()) ::
  Ash.Resource.Validation.ref()
```

Validates that the attribute or list of attributes are `nil`. See `absent/2` for more information.

## Options

* `:at_least` (`t:non_neg_integer/0`) - At least this many must be absent. Defaults to the number of attributes provided

* `:at_most` (`t:non_neg_integer/0`) - At most this many must be absent. Defaults to the number of attributes provided

* `:exactly` (`t:non_neg_integer/0`) - Exactly this many must be absent

# `attributes_present`

```elixir
@spec attributes_present(attributes :: atom() | [atom()], opts :: Keyword.t()) ::
  Ash.Resource.Validation.ref()
```

Validates that the attribute or list of attributes are not `nil`. See `present/2` for more information.

## Options

* `:at_least` (`t:non_neg_integer/0`) - At least this many must be present. Defaults to the number of attributes provided

* `:at_most` (`t:non_neg_integer/0`) - At most this many must be present. Defaults to the number of attributes provided

* `:exactly` (`t:non_neg_integer/0`) - Exactly this many must be present

# `changing`

```elixir
@spec changing(attribute_or_relationship :: atom(), opts :: Keyword.t()) ::
  Ash.Resource.Validation.ref()
```

Validates that an attribute or relationship is being changed

## Examples

    validate changing(:first_name)
    validate changing(:comments)
    validate changing(:comments, touching?: true)

## Options

* `:field` (`t:atom/0`) - Required. The attribute or relationship to check for changes. Using a relationship does not compare old and new value, returning `true` if the value is being touched)

* `:touching?` (`t:atom/0`) - Whether to consider a field as changing if it is just being touched (i.e consider it changed even if it is being changed to its current value) The default value is `false`.

* `:to` (`t:term/0`) - Only passes if the value is being changed to a given value

* `:from` (`t:term/0`) - Only passes if the value is being changed from a given value

# `compare`

```elixir
@spec compare(attribute :: atom(), opts :: Keyword.t()) ::
  Ash.Resource.Validation.ref()
```

Validates that an attribute or argument meets the given comparison criteria.

The values provided for each option may be a literal value, attribute, argument, or a zero argument function.

## Options
* `:greater_than` - The value that the attribute should be greater than.

* `:greater_than_or_equal_to` - The value that the attribute should be greater than or equal to

* `:less_than` - The value that the attribute should be less than

* `:less_than_or_equal_to` - The value that the attribute should be less than or equal to

* `:is_equal` - The value that the attribute should be equal to

* `:is_not_equal` - The value that the attribute should not be equal to

* `:is_nil` (`t:boolean/0`) - Whether the attribute should be nil (true) or not nil (false)

## Examples

    validate compare(:age, greater_than_or_equal_to: 18),
      where: [attribute_equals(:show_adult_content, true)],
      message: "must be over %{greater_than_or_equal_to} to enable adult content."

    validate compare(:points, greater_than: 0, less_than_or_equal_to: 100)

# `confirm`

```elixir
@spec confirm(
  attribute_or_argument :: atom(),
  confirmation_attribute_or_argument :: atom()
) ::
  Ash.Resource.Validation.ref()
```

Validates that a field or argument matches another field or argument

## Examples

    validate confirm(:password, :password_confirmation)
    validate confirm(:email, :email_confirmation)

# `data_one_of`

```elixir
@spec data_one_of(attribute :: atom(), [any()]) :: Ash.Resource.Validation.ref()
```

Validates that the original value is in a given list

## Examples

    validate data_one_of(:status, [:closed_won, :closed_lost])

# `match`

```elixir
@spec match(attribute :: atom(), match :: Regex.t()) :: Ash.Resource.Validation.ref()
```

Validates that an attribute's value matches a given regex.

`String.match?/2` is used to determine if the value matches.

## Examples

    validate match(:slug, "^[0-9a-z-_]+$")

# `negate`

```elixir
@spec negate(validation :: Ash.Resource.Validation.ref()) ::
  Ash.Resource.Validation.ref()
```

Validates that other validation does not pass

## Examples

    validate negate(one_of(:status, [:closed, :finished]))

# `numericality`

```elixir
@spec numericality(attribute :: atom(), opts :: Keyword.t()) ::
  Ash.Resource.Validation.ref()
```

Validates that an attribute or argument meets the given comparison criteria.

The values provided for each option may be a literal value, attribute, argument, or a zero argument function.

## Options
* `:greater_than` - The value that the attribute should be greater than.

* `:greater_than_or_equal_to` - The value that the attribute should be greater than or equal to

* `:less_than` - The value that the attribute should be less than

* `:less_than_or_equal_to` - The value that the attribute should be less than or equal to

* `:is_equal` - The value that the attribute should be equal to

* `:is_not_equal` - The value that the attribute should not be equal to

* `:is_nil` (`t:boolean/0`) - Whether the attribute should be nil (true) or not nil (false)

## Examples

    validate numericality(:age, greater_than_or_equal_to: 18),
      where: [attribute_equals(:show_adult_content, true)],
      message: "must be over %{greater_than_or_equal_to} to enable adult content."

    validate numericality(:points, greater_than: 0, less_than_or_equal_to: 100)

# `one_of`

```elixir
@spec one_of(attribute :: atom(), [any()]) :: Ash.Resource.Validation.ref()
```

Validates that an attribute's value is in a given list

## Examples

    validate one_of(:status, [:closed_won, :closed_lost])

# `pre_flight_authorization`

```elixir
@spec pre_flight_authorization() :: Ash.Resource.Validation.ref()
```

Validates that the action is being run in a pre-flight authorization context (i.e. `Ash.can?/3`).

Primarily meant for use in `where` to skip or enable validations during authorization checks.

## Examples

    # Skip an expensive validation during can/can? checks
    validate expensive_check(), where: [negate(pre_flight_authorization())]

    # Only run a validation during can/can? checks
    validate some_check(), where: [pre_flight_authorization()]

# `present`

```elixir
@spec present(attributes_or_arguments :: atom() | [atom()], opts :: Keyword.t()) ::
  Ash.Resource.Validation.ref()
```

Validates that the given attribute or argument or list of attributes or arguments are not `nil`.

Use options to specify how many must not be `nil`. If no options are provided, validates that they are all present.

Keep in mind that some types cast certain values to `nil`, and validations are
applied after all inputs have been cast. For example, a `:string` type attribute
with the default constraints will cast `""` as `nil`, meaning an input of
`""` would fail the `present` validation.

## Options

* `:at_least` (`t:non_neg_integer/0`) - At least this many must be present. Defaults to the number of attributes provided

* `:at_most` (`t:non_neg_integer/0`) - At most this many must be present. Defaults to the number of attributes provided

* `:exactly` (`t:non_neg_integer/0`) - Exactly this many must be present

## Examples

    validate present(:name)

    validate present([:first_name, :last_name]), where: [absent(:full_name)]

    validate present([:is_admin, :is_normal_user], at_most: 1)

# `string_length`

```elixir
@spec string_length(attribute :: atom(), opts :: Keyword.t()) ::
  Ash.Resource.Validation.ref()
```

Validates that an attribute on the original record meets the given length criteria

## Options

* `:min` (`t:non_neg_integer/0`) - String must be this length at least

* `:max` (`t:non_neg_integer/0`) - String must be this length at most

* `:exact` (`t:non_neg_integer/0`) - String must be this length exactly

## Examples

    validate string_length(:slug, exact: 8)
    validate string_length(:password, min: 6)
    validate string_length(:secret, min: 4, max: 12)

---

*Consult [api-reference.md](api-reference.md) for complete listing*
