mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 13:33:20 +12:00
3539 lines
161 KiB
Markdown
3539 lines
161 KiB
Markdown
<!--
|
|
This file was generated by Spark. Do not edit it by hand.
|
|
-->
|
|
# DSL: Ash.Resource.Dsl
|
|
|
|
|
|
|
|
## attributes
|
|
A section for declaring attributes on the resource.
|
|
|
|
|
|
### Nested DSLs
|
|
* [attribute](#attributes-attribute)
|
|
* [create_timestamp](#attributes-create_timestamp)
|
|
* [update_timestamp](#attributes-update_timestamp)
|
|
* [integer_primary_key](#attributes-integer_primary_key)
|
|
* [uuid_primary_key](#attributes-uuid_primary_key)
|
|
* [uuid_v7_primary_key](#attributes-uuid_v7_primary_key)
|
|
|
|
|
|
### Examples
|
|
```
|
|
attributes do
|
|
uuid_primary_key :id
|
|
|
|
attribute :first_name, :string do
|
|
allow_nil? false
|
|
end
|
|
|
|
attribute :last_name, :string do
|
|
allow_nil? false
|
|
end
|
|
|
|
attribute :email, :string do
|
|
allow_nil? false
|
|
|
|
constraints [
|
|
match: ~r/^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$/
|
|
]
|
|
end
|
|
|
|
attribute :type, :atom do
|
|
constraints [
|
|
one_of: [:admin, :teacher, :student]
|
|
]
|
|
end
|
|
|
|
create_timestamp :inserted_at
|
|
update_timestamp :updated_at
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## attributes.attribute
|
|
```elixir
|
|
attribute name, type
|
|
```
|
|
|
|
|
|
Declares an attribute on the resource.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
attribute :name, :string do
|
|
allow_nil? false
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#attributes-attribute-name){: #attributes-attribute-name .spark-required} | `atom` | | The name of the attribute. |
|
|
| [`type`](#attributes-attribute-type){: #attributes-attribute-type .spark-required} | `module` | | The type of the attribute. See `Ash.Type` for more. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`constraints`](#attributes-attribute-constraints){: #attributes-attribute-constraints } | `keyword` | | Constraints to provide to the type when casting the value. For more, see `Ash.Type`. |
|
|
| [`description`](#attributes-attribute-description){: #attributes-attribute-description } | `String.t` | | An optional description for the attribute. |
|
|
| [`sensitive?`](#attributes-attribute-sensitive?){: #attributes-attribute-sensitive? } | `boolean` | `false` | Whether or not the attribute value contains sensitive information, like PII. See the [Sensitive Data guide](/documentation/topics/security/sensitive-data.md) for more. |
|
|
| [`source`](#attributes-attribute-source){: #attributes-attribute-source } | `atom` | | If the field should be mapped to a different name in the data layer. Support varies by data layer. |
|
|
| [`always_select?`](#attributes-attribute-always_select?){: #attributes-attribute-always_select? } | `boolean` | `false` | Whether or not to ensure this attribute is always selected when reading from the database, regardless of applied select statements. |
|
|
| [`primary_key?`](#attributes-attribute-primary_key?){: #attributes-attribute-primary_key? } | `boolean` | `false` | Whether the attribute is the primary key. Composite primary key is also possible by using `primary_key? true` in more than one attribute. If primary_key? is true, allow_nil? must be false. |
|
|
| [`allow_nil?`](#attributes-attribute-allow_nil?){: #attributes-attribute-allow_nil? } | `boolean` | `true` | Whether or not the attribute can be set to nil. If nil value is given error is raised. |
|
|
| [`generated?`](#attributes-attribute-generated?){: #attributes-attribute-generated? } | `boolean` | `false` | Whether or not the value may be generated by the data layer. |
|
|
| [`writable?`](#attributes-attribute-writable?){: #attributes-attribute-writable? } | `boolean` | `true` | Whether or not the value can be written to. Non-writable attributes can still be written with `Ash.Changeset.force_change_attribute/3`. |
|
|
| [`public?`](#attributes-attribute-public?){: #attributes-attribute-public? } | `boolean` | `false` | Whether or not the attribute should be shown over public interfaces. See the [sensitive data guide](/documentation/topics/security/sensitive-data.md) for more. |
|
|
| [`default`](#attributes-attribute-default){: #attributes-attribute-default } | `(-> any) \| mfa \| any` | | A value to be set on all creates, unless a value is being provided already. Note: The default value is casted according to the type's Ash.Type.* module, before it is saved. For `:string`, for example, if `constraints: [allow_empty?: _]` is false, the value `""` will be cast to `nil`. See the `:constraints` option, the `:allow_nil?` option, and the relevant `Ash.Type.*` documentation. |
|
|
| [`update_default`](#attributes-attribute-update_default){: #attributes-attribute-update_default } | `(-> any) \| mfa \| any` | | A value to be set on all updates, unless a value is being provided already. |
|
|
| [`filterable?`](#attributes-attribute-filterable?){: #attributes-attribute-filterable? } | `boolean \| :simple_equality` | `true` | Whether or not the attribute can be referenced in filters. |
|
|
| [`sortable?`](#attributes-attribute-sortable?){: #attributes-attribute-sortable? } | `boolean` | `true` | Whether or not the attribute can be referenced in sorts. |
|
|
| [`match_other_defaults?`](#attributes-attribute-match_other_defaults?){: #attributes-attribute-match_other_defaults? } | `boolean` | `false` | Ensures that other attributes that use the same "lazy" default (a function or an mfa), use the same default value. Has no effect unless `default` is a zero argument function. |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Attribute`
|
|
|
|
## attributes.create_timestamp
|
|
```elixir
|
|
create_timestamp name
|
|
```
|
|
|
|
|
|
Declares a non-writable attribute with a create default of `&DateTime.utc_now/0`
|
|
|
|
Accepts all the same options as `d:Ash.Resource.Dsl.attributes.attribute`, except it sets
|
|
the following different defaults:
|
|
|
|
writable? false
|
|
default &DateTime.utc_now/0
|
|
match_other_defaults? true
|
|
type Ash.Type.UTCDatetimeUsec
|
|
allow_nil? false
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
create_timestamp :inserted_at
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#attributes-create_timestamp-name){: #attributes-create_timestamp-name .spark-required} | `atom` | | The name of the attribute. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`type`](#attributes-create_timestamp-type){: #attributes-create_timestamp-type } | `module` | `Ash.Type.UtcDatetimeUsec` | The type of the attribute. See `Ash.Type` for more. |
|
|
| [`constraints`](#attributes-create_timestamp-constraints){: #attributes-create_timestamp-constraints } | `keyword` | | Constraints to provide to the type when casting the value. For more, see `Ash.Type`. |
|
|
| [`description`](#attributes-create_timestamp-description){: #attributes-create_timestamp-description } | `String.t` | | An optional description for the attribute. |
|
|
| [`sensitive?`](#attributes-create_timestamp-sensitive?){: #attributes-create_timestamp-sensitive? } | `boolean` | `false` | Whether or not the attribute value contains sensitive information, like PII. See the [Sensitive Data guide](/documentation/topics/security/sensitive-data.md) for more. |
|
|
| [`source`](#attributes-create_timestamp-source){: #attributes-create_timestamp-source } | `atom` | | If the field should be mapped to a different name in the data layer. Support varies by data layer. |
|
|
| [`always_select?`](#attributes-create_timestamp-always_select?){: #attributes-create_timestamp-always_select? } | `boolean` | `false` | Whether or not to ensure this attribute is always selected when reading from the database, regardless of applied select statements. |
|
|
| [`primary_key?`](#attributes-create_timestamp-primary_key?){: #attributes-create_timestamp-primary_key? } | `boolean` | `false` | Whether the attribute is the primary key. Composite primary key is also possible by using `primary_key? true` in more than one attribute. If primary_key? is true, allow_nil? must be false. |
|
|
| [`allow_nil?`](#attributes-create_timestamp-allow_nil?){: #attributes-create_timestamp-allow_nil? } | `boolean` | `false` | Whether or not the attribute can be set to nil. If nil value is given error is raised. |
|
|
| [`generated?`](#attributes-create_timestamp-generated?){: #attributes-create_timestamp-generated? } | `boolean` | `false` | Whether or not the value may be generated by the data layer. |
|
|
| [`writable?`](#attributes-create_timestamp-writable?){: #attributes-create_timestamp-writable? } | `boolean` | `false` | Whether or not the value can be written to. Non-writable attributes can still be written with `Ash.Changeset.force_change_attribute/3`. |
|
|
| [`public?`](#attributes-create_timestamp-public?){: #attributes-create_timestamp-public? } | `boolean` | `false` | Whether or not the attribute should be shown over public interfaces. See the [sensitive data guide](/documentation/topics/security/sensitive-data.md) for more. |
|
|
| [`default`](#attributes-create_timestamp-default){: #attributes-create_timestamp-default } | `(-> any) \| mfa \| any` | `&DateTime.utc_now/0` | A value to be set on all creates, unless a value is being provided already. Note: The default value is casted according to the type's Ash.Type.* module, before it is saved. For `:string`, for example, if `constraints: [allow_empty?: _]` is false, the value `""` will be cast to `nil`. See the `:constraints` option, the `:allow_nil?` option, and the relevant `Ash.Type.*` documentation. |
|
|
| [`update_default`](#attributes-create_timestamp-update_default){: #attributes-create_timestamp-update_default } | `(-> any) \| mfa \| any` | | A value to be set on all updates, unless a value is being provided already. |
|
|
| [`filterable?`](#attributes-create_timestamp-filterable?){: #attributes-create_timestamp-filterable? } | `boolean \| :simple_equality` | `true` | Whether or not the attribute can be referenced in filters. |
|
|
| [`sortable?`](#attributes-create_timestamp-sortable?){: #attributes-create_timestamp-sortable? } | `boolean` | `true` | Whether or not the attribute can be referenced in sorts. |
|
|
| [`match_other_defaults?`](#attributes-create_timestamp-match_other_defaults?){: #attributes-create_timestamp-match_other_defaults? } | `boolean` | `true` | Ensures that other attributes that use the same "lazy" default (a function or an mfa), use the same default value. Has no effect unless `default` is a zero argument function. |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Attribute`
|
|
|
|
## attributes.update_timestamp
|
|
```elixir
|
|
update_timestamp name
|
|
```
|
|
|
|
|
|
Declares a non-writable attribute with a create and update default of `&DateTime.utc_now/0`
|
|
|
|
Accepts all the same options as `d:Ash.Resource.Dsl.attributes.attribute`, except it sets
|
|
the following different defaults:
|
|
|
|
writable? false
|
|
default &DateTime.utc_now/0
|
|
match_other_defaults? true
|
|
update_default &DateTime.utc_now/0
|
|
type Ash.Type.UTCDatetimeUsec
|
|
allow_nil? false
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
update_timestamp :updated_at
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#attributes-update_timestamp-name){: #attributes-update_timestamp-name .spark-required} | `atom` | | The name of the attribute. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`type`](#attributes-update_timestamp-type){: #attributes-update_timestamp-type } | `module` | `Ash.Type.UtcDatetimeUsec` | The type of the attribute. See `Ash.Type` for more. |
|
|
| [`constraints`](#attributes-update_timestamp-constraints){: #attributes-update_timestamp-constraints } | `keyword` | | Constraints to provide to the type when casting the value. For more, see `Ash.Type`. |
|
|
| [`description`](#attributes-update_timestamp-description){: #attributes-update_timestamp-description } | `String.t` | | An optional description for the attribute. |
|
|
| [`sensitive?`](#attributes-update_timestamp-sensitive?){: #attributes-update_timestamp-sensitive? } | `boolean` | `false` | Whether or not the attribute value contains sensitive information, like PII. See the [Sensitive Data guide](/documentation/topics/security/sensitive-data.md) for more. |
|
|
| [`source`](#attributes-update_timestamp-source){: #attributes-update_timestamp-source } | `atom` | | If the field should be mapped to a different name in the data layer. Support varies by data layer. |
|
|
| [`always_select?`](#attributes-update_timestamp-always_select?){: #attributes-update_timestamp-always_select? } | `boolean` | `false` | Whether or not to ensure this attribute is always selected when reading from the database, regardless of applied select statements. |
|
|
| [`primary_key?`](#attributes-update_timestamp-primary_key?){: #attributes-update_timestamp-primary_key? } | `boolean` | `false` | Whether the attribute is the primary key. Composite primary key is also possible by using `primary_key? true` in more than one attribute. If primary_key? is true, allow_nil? must be false. |
|
|
| [`allow_nil?`](#attributes-update_timestamp-allow_nil?){: #attributes-update_timestamp-allow_nil? } | `boolean` | `false` | Whether or not the attribute can be set to nil. If nil value is given error is raised. |
|
|
| [`generated?`](#attributes-update_timestamp-generated?){: #attributes-update_timestamp-generated? } | `boolean` | `false` | Whether or not the value may be generated by the data layer. |
|
|
| [`writable?`](#attributes-update_timestamp-writable?){: #attributes-update_timestamp-writable? } | `boolean` | `false` | Whether or not the value can be written to. Non-writable attributes can still be written with `Ash.Changeset.force_change_attribute/3`. |
|
|
| [`public?`](#attributes-update_timestamp-public?){: #attributes-update_timestamp-public? } | `boolean` | `false` | Whether or not the attribute should be shown over public interfaces. See the [sensitive data guide](/documentation/topics/security/sensitive-data.md) for more. |
|
|
| [`default`](#attributes-update_timestamp-default){: #attributes-update_timestamp-default } | `(-> any) \| mfa \| any` | `&DateTime.utc_now/0` | A value to be set on all creates, unless a value is being provided already. Note: The default value is casted according to the type's Ash.Type.* module, before it is saved. For `:string`, for example, if `constraints: [allow_empty?: _]` is false, the value `""` will be cast to `nil`. See the `:constraints` option, the `:allow_nil?` option, and the relevant `Ash.Type.*` documentation. |
|
|
| [`update_default`](#attributes-update_timestamp-update_default){: #attributes-update_timestamp-update_default } | `(-> any) \| mfa \| any` | `&DateTime.utc_now/0` | A value to be set on all updates, unless a value is being provided already. |
|
|
| [`filterable?`](#attributes-update_timestamp-filterable?){: #attributes-update_timestamp-filterable? } | `boolean \| :simple_equality` | `true` | Whether or not the attribute can be referenced in filters. |
|
|
| [`sortable?`](#attributes-update_timestamp-sortable?){: #attributes-update_timestamp-sortable? } | `boolean` | `true` | Whether or not the attribute can be referenced in sorts. |
|
|
| [`match_other_defaults?`](#attributes-update_timestamp-match_other_defaults?){: #attributes-update_timestamp-match_other_defaults? } | `boolean` | `true` | Ensures that other attributes that use the same "lazy" default (a function or an mfa), use the same default value. Has no effect unless `default` is a zero argument function. |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Attribute`
|
|
|
|
## attributes.integer_primary_key
|
|
```elixir
|
|
integer_primary_key name
|
|
```
|
|
|
|
|
|
Declares a generated, non writable, non-nil, primary key column of type integer.
|
|
|
|
Generated integer primary keys must be supported by the data layer.
|
|
|
|
Accepts all the same options as `d:Ash.Resource.Dsl.attributes.attribute`, except for `allow_nil?`, but it sets
|
|
the following different defaults:
|
|
|
|
public? true
|
|
writable? false
|
|
primary_key? true
|
|
generated? true
|
|
type :integer
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
integer_primary_key :id
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#attributes-integer_primary_key-name){: #attributes-integer_primary_key-name .spark-required} | `atom` | | The name of the attribute. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`type`](#attributes-integer_primary_key-type){: #attributes-integer_primary_key-type } | `module` | `:integer` | The type of the attribute. See `Ash.Type` for more. |
|
|
| [`constraints`](#attributes-integer_primary_key-constraints){: #attributes-integer_primary_key-constraints } | `keyword` | | Constraints to provide to the type when casting the value. For more, see `Ash.Type`. |
|
|
| [`description`](#attributes-integer_primary_key-description){: #attributes-integer_primary_key-description } | `String.t` | | An optional description for the attribute. |
|
|
| [`sensitive?`](#attributes-integer_primary_key-sensitive?){: #attributes-integer_primary_key-sensitive? } | `boolean` | `false` | Whether or not the attribute value contains sensitive information, like PII. See the [Sensitive Data guide](/documentation/topics/security/sensitive-data.md) for more. |
|
|
| [`source`](#attributes-integer_primary_key-source){: #attributes-integer_primary_key-source } | `atom` | | If the field should be mapped to a different name in the data layer. Support varies by data layer. |
|
|
| [`always_select?`](#attributes-integer_primary_key-always_select?){: #attributes-integer_primary_key-always_select? } | `boolean` | `false` | Whether or not to ensure this attribute is always selected when reading from the database, regardless of applied select statements. |
|
|
| [`primary_key?`](#attributes-integer_primary_key-primary_key?){: #attributes-integer_primary_key-primary_key? } | `boolean` | `true` | Whether the attribute is the primary key. Composite primary key is also possible by using `primary_key? true` in more than one attribute. If primary_key? is true, allow_nil? must be false. |
|
|
| [`generated?`](#attributes-integer_primary_key-generated?){: #attributes-integer_primary_key-generated? } | `boolean` | `true` | Whether or not the value may be generated by the data layer. |
|
|
| [`writable?`](#attributes-integer_primary_key-writable?){: #attributes-integer_primary_key-writable? } | `boolean` | `false` | Whether or not the value can be written to. Non-writable attributes can still be written with `Ash.Changeset.force_change_attribute/3`. |
|
|
| [`public?`](#attributes-integer_primary_key-public?){: #attributes-integer_primary_key-public? } | `boolean` | `true` | Whether or not the attribute should be shown over public interfaces. See the [sensitive data guide](/documentation/topics/security/sensitive-data.md) for more. |
|
|
| [`default`](#attributes-integer_primary_key-default){: #attributes-integer_primary_key-default } | `(-> any) \| mfa \| any` | | A value to be set on all creates, unless a value is being provided already. Note: The default value is casted according to the type's Ash.Type.* module, before it is saved. For `:string`, for example, if `constraints: [allow_empty?: _]` is false, the value `""` will be cast to `nil`. See the `:constraints` option, the `:allow_nil?` option, and the relevant `Ash.Type.*` documentation. |
|
|
| [`update_default`](#attributes-integer_primary_key-update_default){: #attributes-integer_primary_key-update_default } | `(-> any) \| mfa \| any` | | A value to be set on all updates, unless a value is being provided already. |
|
|
| [`filterable?`](#attributes-integer_primary_key-filterable?){: #attributes-integer_primary_key-filterable? } | `boolean \| :simple_equality` | `true` | Whether or not the attribute can be referenced in filters. |
|
|
| [`sortable?`](#attributes-integer_primary_key-sortable?){: #attributes-integer_primary_key-sortable? } | `boolean` | `true` | Whether or not the attribute can be referenced in sorts. |
|
|
| [`match_other_defaults?`](#attributes-integer_primary_key-match_other_defaults?){: #attributes-integer_primary_key-match_other_defaults? } | `boolean` | `false` | Ensures that other attributes that use the same "lazy" default (a function or an mfa), use the same default value. Has no effect unless `default` is a zero argument function. |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Attribute`
|
|
|
|
## attributes.uuid_primary_key
|
|
```elixir
|
|
uuid_primary_key name
|
|
```
|
|
|
|
|
|
Declares a non writable, non-nil, primary key column of type `uuid`, which defaults to `Ash.UUID.generate/0`.
|
|
|
|
Accepts all the same options as `d:Ash.Resource.Dsl.attributes.attribute`, except for `allow_nil?`, but it sets
|
|
the following different defaults:
|
|
|
|
writable? false
|
|
public? true
|
|
default &Ash.UUID.generate/0
|
|
primary_key? true
|
|
type :uuid
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
uuid_primary_key :id
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#attributes-uuid_primary_key-name){: #attributes-uuid_primary_key-name .spark-required} | `atom` | | The name of the attribute. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`type`](#attributes-uuid_primary_key-type){: #attributes-uuid_primary_key-type } | `module` | `:uuid` | The type of the attribute. See `Ash.Type` for more. |
|
|
| [`constraints`](#attributes-uuid_primary_key-constraints){: #attributes-uuid_primary_key-constraints } | `keyword` | | Constraints to provide to the type when casting the value. For more, see `Ash.Type`. |
|
|
| [`description`](#attributes-uuid_primary_key-description){: #attributes-uuid_primary_key-description } | `String.t` | | An optional description for the attribute. |
|
|
| [`sensitive?`](#attributes-uuid_primary_key-sensitive?){: #attributes-uuid_primary_key-sensitive? } | `boolean` | `false` | Whether or not the attribute value contains sensitive information, like PII. See the [Sensitive Data guide](/documentation/topics/security/sensitive-data.md) for more. |
|
|
| [`source`](#attributes-uuid_primary_key-source){: #attributes-uuid_primary_key-source } | `atom` | | If the field should be mapped to a different name in the data layer. Support varies by data layer. |
|
|
| [`always_select?`](#attributes-uuid_primary_key-always_select?){: #attributes-uuid_primary_key-always_select? } | `boolean` | `false` | Whether or not to ensure this attribute is always selected when reading from the database, regardless of applied select statements. |
|
|
| [`primary_key?`](#attributes-uuid_primary_key-primary_key?){: #attributes-uuid_primary_key-primary_key? } | `boolean` | `true` | Whether the attribute is the primary key. Composite primary key is also possible by using `primary_key? true` in more than one attribute. If primary_key? is true, allow_nil? must be false. |
|
|
| [`generated?`](#attributes-uuid_primary_key-generated?){: #attributes-uuid_primary_key-generated? } | `boolean` | `false` | Whether or not the value may be generated by the data layer. |
|
|
| [`writable?`](#attributes-uuid_primary_key-writable?){: #attributes-uuid_primary_key-writable? } | `boolean` | `false` | Whether or not the value can be written to. Non-writable attributes can still be written with `Ash.Changeset.force_change_attribute/3`. |
|
|
| [`public?`](#attributes-uuid_primary_key-public?){: #attributes-uuid_primary_key-public? } | `boolean` | `true` | Whether or not the attribute should be shown over public interfaces. See the [sensitive data guide](/documentation/topics/security/sensitive-data.md) for more. |
|
|
| [`default`](#attributes-uuid_primary_key-default){: #attributes-uuid_primary_key-default } | `(-> any) \| mfa \| any` | `&Ash.UUID.generate/0` | A value to be set on all creates, unless a value is being provided already. Note: The default value is casted according to the type's Ash.Type.* module, before it is saved. For `:string`, for example, if `constraints: [allow_empty?: _]` is false, the value `""` will be cast to `nil`. See the `:constraints` option, the `:allow_nil?` option, and the relevant `Ash.Type.*` documentation. |
|
|
| [`update_default`](#attributes-uuid_primary_key-update_default){: #attributes-uuid_primary_key-update_default } | `(-> any) \| mfa \| any` | | A value to be set on all updates, unless a value is being provided already. |
|
|
| [`filterable?`](#attributes-uuid_primary_key-filterable?){: #attributes-uuid_primary_key-filterable? } | `boolean \| :simple_equality` | `true` | Whether or not the attribute can be referenced in filters. |
|
|
| [`sortable?`](#attributes-uuid_primary_key-sortable?){: #attributes-uuid_primary_key-sortable? } | `boolean` | `true` | Whether or not the attribute can be referenced in sorts. |
|
|
| [`match_other_defaults?`](#attributes-uuid_primary_key-match_other_defaults?){: #attributes-uuid_primary_key-match_other_defaults? } | `boolean` | `false` | Ensures that other attributes that use the same "lazy" default (a function or an mfa), use the same default value. Has no effect unless `default` is a zero argument function. |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Attribute`
|
|
|
|
## attributes.uuid_v7_primary_key
|
|
```elixir
|
|
uuid_v7_primary_key name
|
|
```
|
|
|
|
|
|
Declares a non writable, non-nil, primary key column of type `uuid_v7`, which defaults to `Ash.UUIDv7.generate/0`.
|
|
|
|
Accepts all the same options as `d:Ash.Resource.Dsl.attributes.attribute`, except for `allow_nil?`, but it sets
|
|
the following different defaults:
|
|
|
|
writable? false
|
|
public? true
|
|
default &Ash.UUIDv7.generate/0
|
|
primary_key? true
|
|
type :uuid_v7
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
uuid_v7_primary_key :id
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#attributes-uuid_v7_primary_key-name){: #attributes-uuid_v7_primary_key-name .spark-required} | `atom` | | The name of the attribute. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`type`](#attributes-uuid_v7_primary_key-type){: #attributes-uuid_v7_primary_key-type } | `module` | `:uuid_v7` | The type of the attribute. See `Ash.Type` for more. |
|
|
| [`constraints`](#attributes-uuid_v7_primary_key-constraints){: #attributes-uuid_v7_primary_key-constraints } | `keyword` | | Constraints to provide to the type when casting the value. For more, see `Ash.Type`. |
|
|
| [`description`](#attributes-uuid_v7_primary_key-description){: #attributes-uuid_v7_primary_key-description } | `String.t` | | An optional description for the attribute. |
|
|
| [`sensitive?`](#attributes-uuid_v7_primary_key-sensitive?){: #attributes-uuid_v7_primary_key-sensitive? } | `boolean` | `false` | Whether or not the attribute value contains sensitive information, like PII. See the [Sensitive Data guide](/documentation/topics/security/sensitive-data.md) for more. |
|
|
| [`source`](#attributes-uuid_v7_primary_key-source){: #attributes-uuid_v7_primary_key-source } | `atom` | | If the field should be mapped to a different name in the data layer. Support varies by data layer. |
|
|
| [`always_select?`](#attributes-uuid_v7_primary_key-always_select?){: #attributes-uuid_v7_primary_key-always_select? } | `boolean` | `false` | Whether or not to ensure this attribute is always selected when reading from the database, regardless of applied select statements. |
|
|
| [`primary_key?`](#attributes-uuid_v7_primary_key-primary_key?){: #attributes-uuid_v7_primary_key-primary_key? } | `boolean` | `true` | Whether the attribute is the primary key. Composite primary key is also possible by using `primary_key? true` in more than one attribute. If primary_key? is true, allow_nil? must be false. |
|
|
| [`generated?`](#attributes-uuid_v7_primary_key-generated?){: #attributes-uuid_v7_primary_key-generated? } | `boolean` | `false` | Whether or not the value may be generated by the data layer. |
|
|
| [`writable?`](#attributes-uuid_v7_primary_key-writable?){: #attributes-uuid_v7_primary_key-writable? } | `boolean` | `false` | Whether or not the value can be written to. Non-writable attributes can still be written with `Ash.Changeset.force_change_attribute/3`. |
|
|
| [`public?`](#attributes-uuid_v7_primary_key-public?){: #attributes-uuid_v7_primary_key-public? } | `boolean` | `true` | Whether or not the attribute should be shown over public interfaces. See the [sensitive data guide](/documentation/topics/security/sensitive-data.md) for more. |
|
|
| [`default`](#attributes-uuid_v7_primary_key-default){: #attributes-uuid_v7_primary_key-default } | `(-> any) \| mfa \| any` | `&Ash.UUIDv7.generate/0` | A value to be set on all creates, unless a value is being provided already. Note: The default value is casted according to the type's Ash.Type.* module, before it is saved. For `:string`, for example, if `constraints: [allow_empty?: _]` is false, the value `""` will be cast to `nil`. See the `:constraints` option, the `:allow_nil?` option, and the relevant `Ash.Type.*` documentation. |
|
|
| [`update_default`](#attributes-uuid_v7_primary_key-update_default){: #attributes-uuid_v7_primary_key-update_default } | `(-> any) \| mfa \| any` | | A value to be set on all updates, unless a value is being provided already. |
|
|
| [`filterable?`](#attributes-uuid_v7_primary_key-filterable?){: #attributes-uuid_v7_primary_key-filterable? } | `boolean \| :simple_equality` | `true` | Whether or not the attribute can be referenced in filters. |
|
|
| [`sortable?`](#attributes-uuid_v7_primary_key-sortable?){: #attributes-uuid_v7_primary_key-sortable? } | `boolean` | `true` | Whether or not the attribute can be referenced in sorts. |
|
|
| [`match_other_defaults?`](#attributes-uuid_v7_primary_key-match_other_defaults?){: #attributes-uuid_v7_primary_key-match_other_defaults? } | `boolean` | `false` | Ensures that other attributes that use the same "lazy" default (a function or an mfa), use the same default value. Has no effect unless `default` is a zero argument function. |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Attribute`
|
|
|
|
|
|
|
|
|
|
## relationships
|
|
A section for declaring relationships on the resource.
|
|
|
|
Relationships are a core component of resource oriented design. Many components of Ash
|
|
will use these relationships. A simple use case is loading relationships (done via the `Ash.Query.load/2`).
|
|
|
|
See the [relationships guide](/documentation/topics/resources/relationships.md) for more.
|
|
|
|
|
|
### Nested DSLs
|
|
* [has_one](#relationships-has_one)
|
|
* filter
|
|
* [has_many](#relationships-has_many)
|
|
* filter
|
|
* [many_to_many](#relationships-many_to_many)
|
|
* filter
|
|
* [belongs_to](#relationships-belongs_to)
|
|
* filter
|
|
|
|
|
|
### Examples
|
|
```
|
|
relationships do
|
|
belongs_to :post, MyApp.Post do
|
|
primary_key? true
|
|
end
|
|
|
|
belongs_to :category, MyApp.Category do
|
|
primary_key? true
|
|
end
|
|
end
|
|
|
|
```
|
|
|
|
```
|
|
relationships do
|
|
belongs_to :author, MyApp.Author
|
|
|
|
many_to_many :categories, MyApp.Category do
|
|
through MyApp.PostCategory
|
|
destination_attribute_on_join_resource :category_id
|
|
source_attribute_on_join_resource :post_id
|
|
end
|
|
end
|
|
|
|
```
|
|
|
|
```
|
|
relationships do
|
|
has_many :posts, MyApp.Post do
|
|
destination_attribute :author_id
|
|
end
|
|
|
|
has_many :composite_key_posts, MyApp.CompositeKeyPost do
|
|
destination_attribute :author_id
|
|
end
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## relationships.has_one
|
|
```elixir
|
|
has_one name, destination
|
|
```
|
|
|
|
|
|
Declares a `has_one` relationship. In a relational database, the foreign key would be on the *other* table.
|
|
|
|
Generally speaking, a `has_one` also implies that the destination table is unique on that foreign key.
|
|
|
|
See the [relationships guide](/documentation/topics/resources/relationships.md) for more.
|
|
|
|
|
|
### Nested DSLs
|
|
* [filter](#relationships-has_one-filter)
|
|
|
|
|
|
### Examples
|
|
```
|
|
# In a resource called `Word`
|
|
has_one :dictionary_entry, DictionaryEntry do
|
|
source_attribute :text
|
|
destination_attribute :word_text
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#relationships-has_one-name){: #relationships-has_one-name } | `atom` | | The name of the relationship |
|
|
| [`destination`](#relationships-has_one-destination){: #relationships-has_one-destination } | `module` | | The destination resource |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`manual`](#relationships-has_one-manual){: #relationships-has_one-manual } | `(any, any -> any) \| module` | | A module that implements `Ash.Resource.ManualRelationship`. Also accepts a 2 argument function that takes the source records and the context. |
|
|
| [`no_attributes?`](#relationships-has_one-no_attributes?){: #relationships-has_one-no_attributes? } | `boolean` | | All existing entities are considered related, i.e this relationship is not based on any fields, and `source_attribute` and `destination_attribute` are ignored. See the See the [relationships guide](/documentation/topics/resources/relationships.md) for more. |
|
|
| [`allow_nil?`](#relationships-has_one-allow_nil?){: #relationships-has_one-allow_nil? } | `boolean` | `true` | Marks the relationship as required. Has no effect on validations, but can inform extensions that there will always be a related entity. |
|
|
| [`from_many?`](#relationships-has_one-from_many?){: #relationships-has_one-from_many? } | `boolean` | `false` | Signal that this relationship is actually a `has_many` where the first record is given via the `sort`. This will allow data layers to properly deduplicate when necessary. |
|
|
| [`description`](#relationships-has_one-description){: #relationships-has_one-description } | `String.t` | | An optional description for the relationship |
|
|
| [`destination_attribute`](#relationships-has_one-destination_attribute){: #relationships-has_one-destination_attribute } | `atom` | | The attribute on the related resource that should match the `source_attribute` configured on this resource. |
|
|
| [`validate_destination_attribute?`](#relationships-has_one-validate_destination_attribute?){: #relationships-has_one-validate_destination_attribute? } | `boolean` | `true` | Whether or not to validate that the destination field exists on the destination resource |
|
|
| [`source_attribute`](#relationships-has_one-source_attribute){: #relationships-has_one-source_attribute } | `atom` | `:id` | The field on this resource that should match the `destination_attribute` on the related resource. |
|
|
| [`relationship_context`](#relationships-has_one-relationship_context){: #relationships-has_one-relationship_context } | `any` | | Context to be set on any queries or changesets generated for managing or querying this relationship. |
|
|
| [`public?`](#relationships-has_one-public?){: #relationships-has_one-public? } | `boolean` | `false` | Whether or not the relationship will appear in public interfaces |
|
|
| [`not_found_message`](#relationships-has_one-not_found_message){: #relationships-has_one-not_found_message } | `String.t` | | A message to show if there is a conflict with this relationship in the database on update or create, or when managing relationships. |
|
|
| [`writable?`](#relationships-has_one-writable?){: #relationships-has_one-writable? } | `boolean` | `true` | Whether or not the relationship may be managed. |
|
|
| [`read_action`](#relationships-has_one-read_action){: #relationships-has_one-read_action } | `atom` | | The read action on the destination resource to use when loading data and filtering. |
|
|
| [`domain`](#relationships-has_one-domain){: #relationships-has_one-domain } | `atom` | | The domain module to use when working with the related entity. |
|
|
| [`filterable?`](#relationships-has_one-filterable?){: #relationships-has_one-filterable? } | `boolean` | `true` | If set to `false`, the relationship will not be usable in filters. |
|
|
| [`sortable?`](#relationships-has_one-sortable?){: #relationships-has_one-sortable? } | `boolean` | `true` | If set to `false`, the relationship will not be usable in filters. |
|
|
| [`sort`](#relationships-has_one-sort){: #relationships-has_one-sort } | `any` | | A sort statement to be applied when loading the relationship. |
|
|
| [`could_be_related_at_creation?`](#relationships-has_one-could_be_related_at_creation?){: #relationships-has_one-could_be_related_at_creation? } | `boolean` | `false` | Whether or not related values may exist for this relationship at creation. |
|
|
| [`violation_message`](#relationships-has_one-violation_message){: #relationships-has_one-violation_message } | `String.t` | | A message to show if there is a conflict with this relationship in the database on destroy. |
|
|
|
|
|
|
## relationships.has_one.filter
|
|
```elixir
|
|
filter filter
|
|
```
|
|
|
|
|
|
Applies a filter. Can use `^arg/1`, `^context/1` and `^actor/1` teplates. Multiple filters are combined with *and*.
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
filter expr(first_name == "fred")
|
|
filter expr(last_name == "weasley" and magician == true)
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`filter`](#relationships-has_one-filter-filter){: #relationships-has_one-filter-filter .spark-required} | `any` | | The filter to apply. Can use `^arg/1`, `^context/1` and `^actor/1` teplates. Multiple filters are combined with *and*. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Dsl.Filter`
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Relationships.HasOne`
|
|
|
|
## relationships.has_many
|
|
```elixir
|
|
has_many name, destination
|
|
```
|
|
|
|
|
|
Declares a `has_many` relationship. There can be any number of related entities.
|
|
|
|
See the [relationships guide](/documentation/topics/resources/relationships.md) for more.
|
|
|
|
|
|
### Nested DSLs
|
|
* [filter](#relationships-has_many-filter)
|
|
|
|
|
|
### Examples
|
|
```
|
|
# In a resource called `Word`
|
|
has_many :definitions, DictionaryDefinition do
|
|
source_attribute :text
|
|
destination_attribute :word_text
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#relationships-has_many-name){: #relationships-has_many-name } | `atom` | | The name of the relationship |
|
|
| [`destination`](#relationships-has_many-destination){: #relationships-has_many-destination } | `module` | | The destination resource |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`manual`](#relationships-has_many-manual){: #relationships-has_many-manual } | `(any, any -> any) \| module` | | A module that implements `Ash.Resource.ManualRelationship`. Also accepts a 2 argument function that takes the source records and the context. |
|
|
| [`no_attributes?`](#relationships-has_many-no_attributes?){: #relationships-has_many-no_attributes? } | `boolean` | | All existing entities are considered related, i.e this relationship is not based on any fields, and `source_attribute` and `destination_attribute` are ignored. See the See the [relationships guide](/documentation/topics/resources/relationships.md) for more. |
|
|
| [`description`](#relationships-has_many-description){: #relationships-has_many-description } | `String.t` | | An optional description for the relationship |
|
|
| [`destination_attribute`](#relationships-has_many-destination_attribute){: #relationships-has_many-destination_attribute } | `atom` | | The attribute on the related resource that should match the `source_attribute` configured on this resource. |
|
|
| [`validate_destination_attribute?`](#relationships-has_many-validate_destination_attribute?){: #relationships-has_many-validate_destination_attribute? } | `boolean` | `true` | Whether or not to validate that the destination field exists on the destination resource |
|
|
| [`source_attribute`](#relationships-has_many-source_attribute){: #relationships-has_many-source_attribute } | `atom` | `:id` | The field on this resource that should match the `destination_attribute` on the related resource. |
|
|
| [`relationship_context`](#relationships-has_many-relationship_context){: #relationships-has_many-relationship_context } | `any` | | Context to be set on any queries or changesets generated for managing or querying this relationship. |
|
|
| [`public?`](#relationships-has_many-public?){: #relationships-has_many-public? } | `boolean` | `false` | Whether or not the relationship will appear in public interfaces |
|
|
| [`not_found_message`](#relationships-has_many-not_found_message){: #relationships-has_many-not_found_message } | `String.t` | | A message to show if there is a conflict with this relationship in the database on update or create, or when managing relationships. |
|
|
| [`writable?`](#relationships-has_many-writable?){: #relationships-has_many-writable? } | `boolean` | `true` | Whether or not the relationship may be managed. |
|
|
| [`read_action`](#relationships-has_many-read_action){: #relationships-has_many-read_action } | `atom` | | The read action on the destination resource to use when loading data and filtering. |
|
|
| [`domain`](#relationships-has_many-domain){: #relationships-has_many-domain } | `atom` | | The domain module to use when working with the related entity. |
|
|
| [`filterable?`](#relationships-has_many-filterable?){: #relationships-has_many-filterable? } | `boolean` | `true` | If set to `false`, the relationship will not be usable in filters. |
|
|
| [`sortable?`](#relationships-has_many-sortable?){: #relationships-has_many-sortable? } | `boolean` | `true` | If set to `false`, the relationship will not be usable in filters. |
|
|
| [`sort`](#relationships-has_many-sort){: #relationships-has_many-sort } | `any` | | A sort statement to be applied when loading the relationship. |
|
|
| [`could_be_related_at_creation?`](#relationships-has_many-could_be_related_at_creation?){: #relationships-has_many-could_be_related_at_creation? } | `boolean` | `false` | Whether or not related values may exist for this relationship at creation. |
|
|
| [`violation_message`](#relationships-has_many-violation_message){: #relationships-has_many-violation_message } | `String.t` | | A message to show if there is a conflict with this relationship in the database on destroy. |
|
|
|
|
|
|
## relationships.has_many.filter
|
|
```elixir
|
|
filter filter
|
|
```
|
|
|
|
|
|
Applies a filter. Can use `^arg/1`, `^context/1` and `^actor/1` teplates. Multiple filters are combined with *and*.
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
filter expr(first_name == "fred")
|
|
filter expr(last_name == "weasley" and magician == true)
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`filter`](#relationships-has_many-filter-filter){: #relationships-has_many-filter-filter .spark-required} | `any` | | The filter to apply. Can use `^arg/1`, `^context/1` and `^actor/1` teplates. Multiple filters are combined with *and*. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Dsl.Filter`
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Relationships.HasMany`
|
|
|
|
## relationships.many_to_many
|
|
```elixir
|
|
many_to_many name, destination
|
|
```
|
|
|
|
|
|
Declares a `many_to_many` relationship. Many to many relationships require a join resource.
|
|
|
|
A join resource is a resource that consists of a relationship to the source and destination of the many to many.
|
|
|
|
See the [relationships guide](/documentation/topics/resources/relationships.md) for more.
|
|
|
|
|
|
### Nested DSLs
|
|
* [filter](#relationships-many_to_many-filter)
|
|
|
|
|
|
### Examples
|
|
```
|
|
# In a resource called `Word`
|
|
many_to_many :books, Book do
|
|
through BookWord
|
|
source_attribute :text
|
|
source_attribute_on_join_resource :word_text
|
|
destination_attribute :id
|
|
destination_attribute_on_join_resource :book_id
|
|
end
|
|
|
|
# And in `BookWord` (the join resource)
|
|
belongs_to :book, Book, primary_key?: true, allow_nil?: false
|
|
belongs_to :word, Word, primary_key?: true, allow_nil?: false
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#relationships-many_to_many-name){: #relationships-many_to_many-name } | `atom` | | The name of the relationship |
|
|
| [`destination`](#relationships-many_to_many-destination){: #relationships-many_to_many-destination } | `module` | | The destination resource |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`source_attribute_on_join_resource`](#relationships-many_to_many-source_attribute_on_join_resource){: #relationships-many_to_many-source_attribute_on_join_resource } | `atom` | | The attribute on the join resource that should line up with `source_attribute` on this resource. Defaults to `<snake_cased_last_part_of_source_module_name>_id`. |
|
|
| [`destination_attribute_on_join_resource`](#relationships-many_to_many-destination_attribute_on_join_resource){: #relationships-many_to_many-destination_attribute_on_join_resource } | `atom` | | The attribute on the join resource that should line up with `destination_attribute` on the related resource. Defaults to `<snake_cased_last_part_of_destination_module_name>_id`. |
|
|
| [`through`](#relationships-many_to_many-through){: #relationships-many_to_many-through } | `module` | | The resource to use as the join resource. |
|
|
| [`join_relationship`](#relationships-many_to_many-join_relationship){: #relationships-many_to_many-join_relationship } | `atom` | | The has_many relationship to the join resource. Defaults to `<relationship_name>_join_assoc`. |
|
|
| [`description`](#relationships-many_to_many-description){: #relationships-many_to_many-description } | `String.t` | | An optional description for the relationship |
|
|
| [`destination_attribute`](#relationships-many_to_many-destination_attribute){: #relationships-many_to_many-destination_attribute } | `atom` | `:id` | The attribute on the related resource that should match the `source_attribute` configured on this resource. |
|
|
| [`validate_destination_attribute?`](#relationships-many_to_many-validate_destination_attribute?){: #relationships-many_to_many-validate_destination_attribute? } | `boolean` | `true` | Whether or not to validate that the destination field exists on the destination resource |
|
|
| [`source_attribute`](#relationships-many_to_many-source_attribute){: #relationships-many_to_many-source_attribute } | `atom` | `:id` | The field on this resource that should match the `destination_attribute` on the related resource. |
|
|
| [`relationship_context`](#relationships-many_to_many-relationship_context){: #relationships-many_to_many-relationship_context } | `any` | | Context to be set on any queries or changesets generated for managing or querying this relationship. |
|
|
| [`public?`](#relationships-many_to_many-public?){: #relationships-many_to_many-public? } | `boolean` | `false` | Whether or not the relationship will appear in public interfaces |
|
|
| [`not_found_message`](#relationships-many_to_many-not_found_message){: #relationships-many_to_many-not_found_message } | `String.t` | | A message to show if there is a conflict with this relationship in the database on update or create, or when managing relationships. |
|
|
| [`writable?`](#relationships-many_to_many-writable?){: #relationships-many_to_many-writable? } | `boolean` | `true` | Whether or not the relationship may be managed. |
|
|
| [`read_action`](#relationships-many_to_many-read_action){: #relationships-many_to_many-read_action } | `atom` | | The read action on the destination resource to use when loading data and filtering. |
|
|
| [`domain`](#relationships-many_to_many-domain){: #relationships-many_to_many-domain } | `atom` | | The domain module to use when working with the related entity. |
|
|
| [`filterable?`](#relationships-many_to_many-filterable?){: #relationships-many_to_many-filterable? } | `boolean` | `true` | If set to `false`, the relationship will not be usable in filters. |
|
|
| [`sortable?`](#relationships-many_to_many-sortable?){: #relationships-many_to_many-sortable? } | `boolean` | `true` | If set to `false`, the relationship will not be usable in filters. |
|
|
| [`sort`](#relationships-many_to_many-sort){: #relationships-many_to_many-sort } | `any` | | A sort statement to be applied when loading the relationship. |
|
|
| [`could_be_related_at_creation?`](#relationships-many_to_many-could_be_related_at_creation?){: #relationships-many_to_many-could_be_related_at_creation? } | `boolean` | `false` | Whether or not related values may exist for this relationship at creation. |
|
|
| [`violation_message`](#relationships-many_to_many-violation_message){: #relationships-many_to_many-violation_message } | `String.t` | | A message to show if there is a conflict with this relationship in the database on destroy. |
|
|
|
|
|
|
## relationships.many_to_many.filter
|
|
```elixir
|
|
filter filter
|
|
```
|
|
|
|
|
|
Applies a filter. Can use `^arg/1`, `^context/1` and `^actor/1` teplates. Multiple filters are combined with *and*.
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
filter expr(first_name == "fred")
|
|
filter expr(last_name == "weasley" and magician == true)
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`filter`](#relationships-many_to_many-filter-filter){: #relationships-many_to_many-filter-filter .spark-required} | `any` | | The filter to apply. Can use `^arg/1`, `^context/1` and `^actor/1` teplates. Multiple filters are combined with *and*. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Dsl.Filter`
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Relationships.ManyToMany`
|
|
|
|
## relationships.belongs_to
|
|
```elixir
|
|
belongs_to name, destination
|
|
```
|
|
|
|
|
|
Declares a `belongs_to` relationship. In a relational database, the foreign key would be on the *source* table.
|
|
|
|
This creates a field on the resource with the corresponding name and type, unless `define_attribute?: false` is provided.
|
|
|
|
See the [relationships guide](/documentation/topics/resources/relationships.md) for more.
|
|
|
|
|
|
### Nested DSLs
|
|
* [filter](#relationships-belongs_to-filter)
|
|
|
|
|
|
### Examples
|
|
```
|
|
# In a resource called `Word`
|
|
belongs_to :dictionary_entry, DictionaryEntry do
|
|
source_attribute :text,
|
|
destination_attribute :word_text
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#relationships-belongs_to-name){: #relationships-belongs_to-name } | `atom` | | The name of the relationship |
|
|
| [`destination`](#relationships-belongs_to-destination){: #relationships-belongs_to-destination } | `module` | | The destination resource |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`primary_key?`](#relationships-belongs_to-primary_key?){: #relationships-belongs_to-primary_key? } | `boolean` | `false` | Whether the generated attribute is, or is part of, the primary key of a resource. |
|
|
| [`allow_nil?`](#relationships-belongs_to-allow_nil?){: #relationships-belongs_to-allow_nil? } | `boolean` | `true` | Whether this relationship must always be present, e.g: must be included on creation, and never removed (it may be modified). The generated attribute will not allow nil values. |
|
|
| [`attribute_writable?`](#relationships-belongs_to-attribute_writable?){: #relationships-belongs_to-attribute_writable? } | `boolean` | | Whether the generated attribute will be marked as writable. If not set, it will default to the relationship's `writable?` setting. |
|
|
| [`attribute_public?`](#relationships-belongs_to-attribute_public?){: #relationships-belongs_to-attribute_public? } | `boolean` | | Whether or not the generated attribute will be public. If not set, it will default to the relationship's `public?` setting. |
|
|
| [`define_attribute?`](#relationships-belongs_to-define_attribute?){: #relationships-belongs_to-define_attribute? } | `boolean` | `true` | If set to `false` an attribute is not created on the resource for this relationship, and one must be manually added in `attributes`, invalidating many other options. |
|
|
| [`attribute_type`](#relationships-belongs_to-attribute_type){: #relationships-belongs_to-attribute_type } | `any` | `:uuid` | The type of the generated created attribute. See `Ash.Type` for more. |
|
|
| [`description`](#relationships-belongs_to-description){: #relationships-belongs_to-description } | `String.t` | | An optional description for the relationship |
|
|
| [`destination_attribute`](#relationships-belongs_to-destination_attribute){: #relationships-belongs_to-destination_attribute } | `atom` | `:id` | The attribute on the related resource that should match the `source_attribute` configured on this resource. |
|
|
| [`validate_destination_attribute?`](#relationships-belongs_to-validate_destination_attribute?){: #relationships-belongs_to-validate_destination_attribute? } | `boolean` | `true` | Whether or not to validate that the destination field exists on the destination resource |
|
|
| [`source_attribute`](#relationships-belongs_to-source_attribute){: #relationships-belongs_to-source_attribute } | `atom` | | The field on this resource that should match the `destination_attribute` on the related resource. - Defaults to <name>_id |
|
|
| [`relationship_context`](#relationships-belongs_to-relationship_context){: #relationships-belongs_to-relationship_context } | `any` | | Context to be set on any queries or changesets generated for managing or querying this relationship. |
|
|
| [`public?`](#relationships-belongs_to-public?){: #relationships-belongs_to-public? } | `boolean` | `false` | Whether or not the relationship will appear in public interfaces |
|
|
| [`not_found_message`](#relationships-belongs_to-not_found_message){: #relationships-belongs_to-not_found_message } | `String.t` | | A message to show if there is a conflict with this relationship in the database on update or create, or when managing relationships. |
|
|
| [`writable?`](#relationships-belongs_to-writable?){: #relationships-belongs_to-writable? } | `boolean` | `true` | Whether or not the relationship may be managed. |
|
|
| [`read_action`](#relationships-belongs_to-read_action){: #relationships-belongs_to-read_action } | `atom` | | The read action on the destination resource to use when loading data and filtering. |
|
|
| [`domain`](#relationships-belongs_to-domain){: #relationships-belongs_to-domain } | `atom` | | The domain module to use when working with the related entity. |
|
|
| [`filterable?`](#relationships-belongs_to-filterable?){: #relationships-belongs_to-filterable? } | `boolean` | `true` | If set to `false`, the relationship will not be usable in filters. |
|
|
| [`sortable?`](#relationships-belongs_to-sortable?){: #relationships-belongs_to-sortable? } | `boolean` | `true` | If set to `false`, the relationship will not be usable in filters. |
|
|
| [`sort`](#relationships-belongs_to-sort){: #relationships-belongs_to-sort } | `any` | | A sort statement to be applied when loading the relationship. |
|
|
| [`violation_message`](#relationships-belongs_to-violation_message){: #relationships-belongs_to-violation_message } | `String.t` | | A message to show if there is a conflict with this relationship in the database on destroy. |
|
|
|
|
|
|
## relationships.belongs_to.filter
|
|
```elixir
|
|
filter filter
|
|
```
|
|
|
|
|
|
Applies a filter. Can use `^arg/1`, `^context/1` and `^actor/1` teplates. Multiple filters are combined with *and*.
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
filter expr(first_name == "fred")
|
|
filter expr(last_name == "weasley" and magician == true)
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`filter`](#relationships-belongs_to-filter-filter){: #relationships-belongs_to-filter-filter .spark-required} | `any` | | The filter to apply. Can use `^arg/1`, `^context/1` and `^actor/1` teplates. Multiple filters are combined with *and*. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Dsl.Filter`
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Relationships.BelongsTo`
|
|
|
|
|
|
|
|
|
|
## actions
|
|
A section for declaring resource actions.
|
|
|
|
All manipulation of data through the underlying data layer happens through actions.
|
|
There are four types of action: `create`, `read`, `update`, and `destroy`. You may
|
|
recognize these from the acronym `CRUD`. You can have multiple actions of the same
|
|
type, as long as they have different names. This is the primary mechanism for customizing
|
|
your resources to conform to your business logic. It is normal and expected to have
|
|
multiple actions of each type in a large application.
|
|
|
|
|
|
### Nested DSLs
|
|
* [action](#actions-action)
|
|
* argument
|
|
* [create](#actions-create)
|
|
* change
|
|
* validate
|
|
* argument
|
|
* metadata
|
|
* [read](#actions-read)
|
|
* argument
|
|
* prepare
|
|
* pagination
|
|
* metadata
|
|
* filter
|
|
* [update](#actions-update)
|
|
* change
|
|
* validate
|
|
* metadata
|
|
* argument
|
|
* [destroy](#actions-destroy)
|
|
* change
|
|
* validate
|
|
* metadata
|
|
* argument
|
|
|
|
|
|
### Examples
|
|
```
|
|
actions do
|
|
create :signup do
|
|
argument :password, :string
|
|
argument :password_confirmation, :string
|
|
validate confirm(:password, :password_confirmation)
|
|
change {MyApp.HashPassword, []} # A custom implemented Change
|
|
end
|
|
|
|
read :me do
|
|
# An action that auto filters to only return the user for the current user
|
|
filter [id: actor(:id)]
|
|
end
|
|
|
|
update :update do
|
|
accept [:first_name, :last_name]
|
|
end
|
|
|
|
destroy do
|
|
change set_attribute(:deleted_at, &DateTime.utc_now/0)
|
|
# This tells it that even though this is a delete action, it
|
|
# should be treated like an update because `deleted_at` is set.
|
|
# This should be coupled with a `base_filter` on the resource
|
|
# or with the read actions having a `filter` for `is_nil: :deleted_at`
|
|
soft? true
|
|
end
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`defaults`](#actions-defaults){: #actions-defaults } | `list(:create \| :read \| :update \| :destroy \| {atom, atom \| list(atom)})` | | Creates a simple action of each specified type, with the same name as the type. These will be `primary?` unless one already exists for that type. Embedded resources, however, have a default of all resource types. |
|
|
| [`default_accept`](#actions-default_accept){: #actions-default_accept } | `list(atom) \| :*` | | A default value for the `accept` option for each action. Use `:*` to accept all public attributes. |
|
|
|
|
|
|
|
|
## actions.action
|
|
```elixir
|
|
action name, returns \\ nil
|
|
```
|
|
|
|
|
|
Declares a generic action. A combination of arguments, a return type and a run function.
|
|
|
|
For calling this action, see the `Ash.Domain` documentation.
|
|
|
|
|
|
### Nested DSLs
|
|
* [argument](#actions-action-argument)
|
|
|
|
|
|
### Examples
|
|
```
|
|
action :top_user_emails, {:array, :string} do
|
|
argument :limit, :integer, default: 10, allow_nil?: false
|
|
run fn input, context ->
|
|
with {:ok, top_users} <- top_users(input.arguments.limit) do
|
|
{:ok, Enum.map(top_users, &(&1.email))}
|
|
end
|
|
end
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#actions-action-name){: #actions-action-name .spark-required} | `atom` | | The name of the action |
|
|
| [`returns`](#actions-action-returns){: #actions-action-returns } | `module` | | The return type of the action. See `Ash.Type` for more. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`constraints`](#actions-action-constraints){: #actions-action-constraints } | `keyword` | | Constraints for the return type. See `Ash.Type` for more. |
|
|
| [`allow_nil?`](#actions-action-allow_nil?){: #actions-action-allow_nil? } | `boolean` | `false` | Whether or not the action can return nil. Unlike attributes & arguments, this defaults to `false`. |
|
|
| [`run`](#actions-action-run){: #actions-action-run } | `(any, any -> any) \| module \| module` | | |
|
|
| [`primary?`](#actions-action-primary?){: #actions-action-primary? } | `boolean` | `false` | Whether or not this action should be used when no action is specified by the caller. |
|
|
| [`description`](#actions-action-description){: #actions-action-description } | `String.t` | | An optional description for the action |
|
|
| [`transaction?`](#actions-action-transaction?){: #actions-action-transaction? } | `boolean` | | Whether or not the action should be run in transactions. Reads default to false, while create/update/destroy actions default to `true`. |
|
|
| [`touches_resources`](#actions-action-touches_resources){: #actions-action-touches_resources } | `list(atom)` | | A list of resources that the action may touch, used when building transactions. |
|
|
|
|
|
|
## actions.action.argument
|
|
```elixir
|
|
argument name, type
|
|
```
|
|
|
|
|
|
Declares an argument on the action
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
argument :password_confirmation, :string
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#actions-action-argument-name){: #actions-action-argument-name .spark-required} | `atom` | | The name of the argument |
|
|
| [`type`](#actions-action-argument-type){: #actions-action-argument-type .spark-required} | `module` | | The type of the argument. See `Ash.Type` for more. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`description`](#actions-action-argument-description){: #actions-action-argument-description } | `String.t` | | An optional description for the argument. |
|
|
| [`constraints`](#actions-action-argument-constraints){: #actions-action-argument-constraints } | `keyword` | `[]` | Constraints to provide to the type when casting the value. For more information, see `Ash.Type`. |
|
|
| [`allow_nil?`](#actions-action-argument-allow_nil?){: #actions-action-argument-allow_nil? } | `boolean` | `true` | Whether or not the argument value may be nil (or may be not provided). If nil value is given error is raised. |
|
|
| [`public?`](#actions-action-argument-public?){: #actions-action-argument-public? } | `boolean` | `true` | Whether or not the argument should appear in public interfaces |
|
|
| [`sensitive?`](#actions-action-argument-sensitive?){: #actions-action-argument-sensitive? } | `boolean` | `false` | Whether or not the argument value contains sensitive information, like PII. See the [security guide](/documentation/topics/security/sensitive-data.md) for more. |
|
|
| [`default`](#actions-action-argument-default){: #actions-action-argument-default } | `any` | | The default value for the argument to take. It can be a zero argument function e.g `&MyMod.my_fun/0` or a value |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Actions.Argument`
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Actions.Action`
|
|
|
|
## actions.create
|
|
```elixir
|
|
create name
|
|
```
|
|
|
|
|
|
Declares a `create` action. For calling this action, see the `Ash.Domain` documentation.
|
|
|
|
|
|
### Nested DSLs
|
|
* [change](#actions-create-change)
|
|
* [validate](#actions-create-validate)
|
|
* [argument](#actions-create-argument)
|
|
* [metadata](#actions-create-metadata)
|
|
|
|
|
|
### Examples
|
|
```
|
|
create :register do
|
|
primary? true
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#actions-create-name){: #actions-create-name .spark-required} | `atom` | | The name of the action |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`manual`](#actions-create-manual){: #actions-create-manual } | `(any, any -> any) \| module` | | Override the creation behavior. Accepts a module or module and opts, or a function that takes the changeset and context. See the [manual actions guide](/documentation/topics/manual-actions.md) for more. |
|
|
| [`upsert?`](#actions-create-upsert?){: #actions-create-upsert? } | `boolean` | `false` | Forces all uses of this action to be treated as an upsert. |
|
|
| [`upsert_identity`](#actions-create-upsert_identity){: #actions-create-upsert_identity } | `atom` | | The identity to use for the upsert. Cannot be overriden by the caller. Ignored if `upsert?` is not set to `true`. |
|
|
| [`upsert_fields`](#actions-create-upsert_fields){: #actions-create-upsert_fields } | `:replace_all \| {:replace, atom \| list(atom)} \| {:replace_all_except, atom \| list(atom)} \| atom \| list(atom)` | | The fields to overwrite in the case of an upsert. If not provided, all fields except for fields set by defaults will be overwritten. |
|
|
| [`primary?`](#actions-create-primary?){: #actions-create-primary? } | `boolean` | `false` | Whether or not this action should be used when no action is specified by the caller. |
|
|
| [`description`](#actions-create-description){: #actions-create-description } | `String.t` | | An optional description for the action |
|
|
| [`transaction?`](#actions-create-transaction?){: #actions-create-transaction? } | `boolean` | | Whether or not the action should be run in transactions. Reads default to false, while create/update/destroy actions default to `true`. |
|
|
| [`touches_resources`](#actions-create-touches_resources){: #actions-create-touches_resources } | `list(atom)` | | A list of resources that the action may touch, used when building transactions. |
|
|
| [`accept`](#actions-create-accept){: #actions-create-accept } | `atom \| list(atom) \| :*` | | The list of attributes to accept. Use `:*` to accept all public attributes. |
|
|
| [`require_attributes`](#actions-create-require_attributes){: #actions-create-require_attributes } | `list(atom)` | | A list of attributes that would normally `allow_nil?`, to require for this action. No need to include attributes that already do not allow nil? |
|
|
| [`allow_nil_input`](#actions-create-allow_nil_input){: #actions-create-allow_nil_input } | `list(atom)` | | A list of attributes that would normally be required, but should not be for this action. They will still be validated just before the data layer step. |
|
|
| [`delay_global_validations?`](#actions-create-delay_global_validations?){: #actions-create-delay_global_validations? } | `boolean` | `false` | If true, global validations will be done in a `before_action` hook, regardless of their configuration on the resource. |
|
|
| [`skip_global_validations?`](#actions-create-skip_global_validations?){: #actions-create-skip_global_validations? } | `boolean` | `false` | If true, global validations will be skipped. Useful for manual actions. |
|
|
| [`error_handler`](#actions-create-error_handler){: #actions-create-error_handler } | `mfa` | | Sets the error handler on the changeset. See `Ash.Changeset.handle_errors/2` for more |
|
|
| [`notifiers`](#actions-create-notifiers){: #actions-create-notifiers } | `list(module)` | | Notifiers that will be called specifically for this action. |
|
|
| [`manual?`](#actions-create-manual?){: #actions-create-manual? } | `boolean` | | Instructs Ash to *skip* the actual update/create/destroy step at the data layer. See the [manual actions guide](/documentation/topics/manual-actions.md) for more. |
|
|
|
|
|
|
## actions.create.change
|
|
```elixir
|
|
change change
|
|
```
|
|
|
|
|
|
A change to be applied to the changeset.
|
|
|
|
See `Ash.Resource.Change` for more.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
change relate_actor(:reporter)
|
|
```
|
|
|
|
```
|
|
change {MyCustomChange, :foo}
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`change`](#actions-create-change-change){: #actions-create-change-change .spark-required} | `(any, any -> any) \| module` | | The module and options for a change. Also accepts a function that takes the changeset and the context. See `Ash.Resource.Change.Builtins` for builtin changes. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`only_when_valid?`](#actions-create-change-only_when_valid?){: #actions-create-change-only_when_valid? } | `boolean` | `false` | If the change should only be run on valid changes. By default, all changes are run unless stated otherwise here. |
|
|
| [`description`](#actions-create-change-description){: #actions-create-change-description } | `String.t` | | An optional description for the change |
|
|
| [`where`](#actions-create-change-where){: #actions-create-change-where } | `(any, any -> any) \| module \| list((any, any -> any) \| module)` | `[]` | Validations that should pass in order for this change to apply. These validations failing will result in this change being ignored. |
|
|
| [`always_atomic?`](#actions-create-change-always_atomic?){: #actions-create-change-always_atomic? } | `boolean` | `false` | By default, changes are only run atomically if all changes will be run atomically or if there is no `change/3` callback defined. Set this to `true` to run it atomically always. |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Change`
|
|
|
|
## actions.create.validate
|
|
```elixir
|
|
validate validation
|
|
```
|
|
|
|
|
|
Declares a validation to be applied to the changeset.
|
|
|
|
See `Ash.Resource.Validation` for more.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
validate changing(:email)
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`validation`](#actions-create-validate-validation){: #actions-create-validate-validation .spark-required} | `(any, any -> any) \| module` | | The module (or module and opts) that implements the `Ash.Resource.Validation` behaviour. Also accepts a function that receives the changeset and its context. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`where`](#actions-create-validate-where){: #actions-create-validate-where } | `(any, any -> any) \| module \| list((any, any -> any) \| module)` | `[]` | Validations that should pass in order for this validation to apply. Any of these validations failing will result in this validation being ignored. |
|
|
| [`only_when_valid?`](#actions-create-validate-only_when_valid?){: #actions-create-validate-only_when_valid? } | `boolean` | `false` | If the validation should only run on valid changes. Useful for expensive validations or validations that depend on valid data. |
|
|
| [`message`](#actions-create-validate-message){: #actions-create-validate-message } | `String.t` | | If provided, overrides any message set by the validation error |
|
|
| [`description`](#actions-create-validate-description){: #actions-create-validate-description } | `String.t` | | An optional description for the validation |
|
|
| [`before_action?`](#actions-create-validate-before_action?){: #actions-create-validate-before_action? } | `boolean` | `false` | If set to `true`, the validation will be run in a before_action hook |
|
|
| [`always_atomic?`](#actions-create-validate-always_atomic?){: #actions-create-validate-always_atomic? } | `boolean` | `false` | By default, validations are only run atomically if all changes will be run atomically or if there is no `validate/2` callback defined. Set this to `true` to run it atomically always. |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Validation`
|
|
|
|
## actions.create.argument
|
|
```elixir
|
|
argument name, type
|
|
```
|
|
|
|
|
|
Declares an argument on the action
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
argument :password_confirmation, :string
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#actions-create-argument-name){: #actions-create-argument-name .spark-required} | `atom` | | The name of the argument |
|
|
| [`type`](#actions-create-argument-type){: #actions-create-argument-type .spark-required} | `module` | | The type of the argument. See `Ash.Type` for more. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`description`](#actions-create-argument-description){: #actions-create-argument-description } | `String.t` | | An optional description for the argument. |
|
|
| [`constraints`](#actions-create-argument-constraints){: #actions-create-argument-constraints } | `keyword` | `[]` | Constraints to provide to the type when casting the value. For more information, see `Ash.Type`. |
|
|
| [`allow_nil?`](#actions-create-argument-allow_nil?){: #actions-create-argument-allow_nil? } | `boolean` | `true` | Whether or not the argument value may be nil (or may be not provided). If nil value is given error is raised. |
|
|
| [`public?`](#actions-create-argument-public?){: #actions-create-argument-public? } | `boolean` | `true` | Whether or not the argument should appear in public interfaces |
|
|
| [`sensitive?`](#actions-create-argument-sensitive?){: #actions-create-argument-sensitive? } | `boolean` | `false` | Whether or not the argument value contains sensitive information, like PII. See the [security guide](/documentation/topics/security/sensitive-data.md) for more. |
|
|
| [`default`](#actions-create-argument-default){: #actions-create-argument-default } | `any` | | The default value for the argument to take. It can be a zero argument function e.g `&MyMod.my_fun/0` or a value |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Actions.Argument`
|
|
|
|
## actions.create.metadata
|
|
```elixir
|
|
metadata name, type
|
|
```
|
|
|
|
|
|
A special kind of attribute that is only added to specific actions. Nothing sets this value, it must be set in a custom
|
|
change after_action hook via `Ash.Resource.put_metadata/3`.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
metadata :api_token, :string, allow_nil?: false
|
|
|
|
```
|
|
|
|
```
|
|
metadata :operation_id, :string, allow_nil?: false
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#actions-create-metadata-name){: #actions-create-metadata-name .spark-required} | `atom` | | The name of the metadata |
|
|
| [`type`](#actions-create-metadata-type){: #actions-create-metadata-type .spark-required} | `any` | | The type of the metadata. See `Ash.Type` for more. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`constraints`](#actions-create-metadata-constraints){: #actions-create-metadata-constraints } | `keyword` | `[]` | Type constraints on the metadata |
|
|
| [`description`](#actions-create-metadata-description){: #actions-create-metadata-description } | `String.t` | | An optional description for the metadata. |
|
|
| [`allow_nil?`](#actions-create-metadata-allow_nil?){: #actions-create-metadata-allow_nil? } | `boolean` | `true` | Whether or not the metadata may return `nil` |
|
|
| [`default`](#actions-create-metadata-default){: #actions-create-metadata-default } | `any` | | The default value for the metadata to take. It can be a zero argument function e.g `&MyMod.my_fun/0` or a value |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Actions.Metadata`
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Actions.Create`
|
|
|
|
## actions.read
|
|
```elixir
|
|
read name
|
|
```
|
|
|
|
|
|
Declares a `read` action. For calling this action, see the `Ash.Domain` documentation.
|
|
|
|
|
|
### Nested DSLs
|
|
* [argument](#actions-read-argument)
|
|
* [prepare](#actions-read-prepare)
|
|
* [pagination](#actions-read-pagination)
|
|
* [metadata](#actions-read-metadata)
|
|
* [filter](#actions-read-filter)
|
|
|
|
|
|
### Examples
|
|
```
|
|
read :read_all do
|
|
primary? true
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#actions-read-name){: #actions-read-name .spark-required} | `atom` | | The name of the action |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`manual`](#actions-read-manual){: #actions-read-manual } | `(any, any, any -> any) \| module` | | Delegates running of the query to the provided module. Accepts a module or module and opts, or a function that takes the ash query, the data layer query, and context. See the [manual actions guide](/documentation/topics/manual-actions.md) for more. |
|
|
| [`get?`](#actions-read-get?){: #actions-read-get? } | `boolean` | `false` | Expresses that this action innately only returns a single result. Used by extensions to validate and/or modify behavior. Causes code interfaces to return a single value instead of a list. See the [code interface guide](/documentation/topics/resources/code-interfaces.md) for more. |
|
|
| [`modify_query`](#actions-read-modify_query){: #actions-read-modify_query } | `mfa \| (any, any -> any)` | | Allows direct manipulation of the data layer query via an MFA. The ash query and the data layer query will be provided as additional arguments. The result must be `{:ok, new_data_layer_query} \| {:error, error}`. |
|
|
| [`get_by`](#actions-read-get_by){: #actions-read-get_by } | `atom \| list(atom)` | | A helper to automatically generate a "get by X" action. Sets `get?` to true, add args for each of the specified fields, and adds a filter for each of the arguments. |
|
|
| [`timeout`](#actions-read-timeout){: #actions-read-timeout } | `pos_integer` | | The maximum amount of time, in milliseconds, that the action is allowed to run for. Ignored if the data layer doesn't support transactions *and* async is disabled. |
|
|
| [`multitenancy`](#actions-read-multitenancy){: #actions-read-multitenancy } | `:enforce \| :allow_global \| :bypass` | `:enforce` | This setting defines how this action handles multitenancy. `:enforce` requires a tenant to be set (the default behavior), `:allow_global` allows using this action both with and without a tenant, `:bypass` completely ignores the tenant even if it's set. This is useful to change the behaviour of selected read action without the need of marking the whole resource with `global? true`. |
|
|
| [`primary?`](#actions-read-primary?){: #actions-read-primary? } | `boolean` | `false` | Whether or not this action should be used when no action is specified by the caller. |
|
|
| [`description`](#actions-read-description){: #actions-read-description } | `String.t` | | An optional description for the action |
|
|
| [`transaction?`](#actions-read-transaction?){: #actions-read-transaction? } | `boolean` | | Whether or not the action should be run in transactions. Reads default to false, while create/update/destroy actions default to `true`. |
|
|
| [`touches_resources`](#actions-read-touches_resources){: #actions-read-touches_resources } | `list(atom)` | | A list of resources that the action may touch, used when building transactions. |
|
|
|
|
|
|
## actions.read.argument
|
|
```elixir
|
|
argument name, type
|
|
```
|
|
|
|
|
|
Declares an argument on the action
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
argument :password_confirmation, :string
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#actions-read-argument-name){: #actions-read-argument-name .spark-required} | `atom` | | The name of the argument |
|
|
| [`type`](#actions-read-argument-type){: #actions-read-argument-type .spark-required} | `module` | | The type of the argument. See `Ash.Type` for more. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`description`](#actions-read-argument-description){: #actions-read-argument-description } | `String.t` | | An optional description for the argument. |
|
|
| [`constraints`](#actions-read-argument-constraints){: #actions-read-argument-constraints } | `keyword` | `[]` | Constraints to provide to the type when casting the value. For more information, see `Ash.Type`. |
|
|
| [`allow_nil?`](#actions-read-argument-allow_nil?){: #actions-read-argument-allow_nil? } | `boolean` | `true` | Whether or not the argument value may be nil (or may be not provided). If nil value is given error is raised. |
|
|
| [`public?`](#actions-read-argument-public?){: #actions-read-argument-public? } | `boolean` | `true` | Whether or not the argument should appear in public interfaces |
|
|
| [`sensitive?`](#actions-read-argument-sensitive?){: #actions-read-argument-sensitive? } | `boolean` | `false` | Whether or not the argument value contains sensitive information, like PII. See the [security guide](/documentation/topics/security/sensitive-data.md) for more. |
|
|
| [`default`](#actions-read-argument-default){: #actions-read-argument-default } | `any` | | The default value for the argument to take. It can be a zero argument function e.g `&MyMod.my_fun/0` or a value |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Actions.Argument`
|
|
|
|
## actions.read.prepare
|
|
```elixir
|
|
prepare preparation
|
|
```
|
|
|
|
|
|
Declares a preparation, which can be used to prepare a query for a read action.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
prepare build(sort: [:foo, :bar])
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`preparation`](#actions-read-prepare-preparation){: #actions-read-prepare-preparation .spark-required} | `(any, any -> any) \| module` | | The module and options for a preparation. Also accepts functions take the query and the context. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Preparation`
|
|
|
|
## actions.read.pagination
|
|
|
|
|
|
Adds pagination options to a resource
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`keyset?`](#actions-read-pagination-keyset?){: #actions-read-pagination-keyset? } | `boolean` | `false` | Whether or not keyset based pagination is supported |
|
|
| [`offset?`](#actions-read-pagination-offset?){: #actions-read-pagination-offset? } | `boolean` | `false` | Whether or not offset based pagination is supported |
|
|
| [`default_limit`](#actions-read-pagination-default_limit){: #actions-read-pagination-default_limit } | `pos_integer` | | The default page size to apply, if one is not supplied |
|
|
| [`countable`](#actions-read-pagination-countable){: #actions-read-pagination-countable } | `true \| false \| :by_default` | `false` | Whether not a returned page will have a full count of all records. Use `:by_default` to do it automatically. |
|
|
| [`max_page_size`](#actions-read-pagination-max_page_size){: #actions-read-pagination-max_page_size } | `pos_integer` | `250` | The maximum amount of records that can be requested in a single page |
|
|
| [`required?`](#actions-read-pagination-required?){: #actions-read-pagination-required? } | `boolean` | `true` | Whether or not pagination can be disabled (by passing `page: false` to `Ash.Api.read!/2`, or by having `required?: false, default_limit: nil` set). Only relevant if some pagination configuration is supplied. |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Actions.Read.Pagination`
|
|
|
|
## actions.read.metadata
|
|
```elixir
|
|
metadata name, type
|
|
```
|
|
|
|
|
|
A special kind of attribute that is only added to specific actions. Nothing sets this value, it must be set in a custom
|
|
change after_action hook via `Ash.Resource.put_metadata/3`.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
metadata :api_token, :string, allow_nil?: false
|
|
|
|
```
|
|
|
|
```
|
|
metadata :operation_id, :string, allow_nil?: false
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#actions-read-metadata-name){: #actions-read-metadata-name .spark-required} | `atom` | | The name of the metadata |
|
|
| [`type`](#actions-read-metadata-type){: #actions-read-metadata-type .spark-required} | `any` | | The type of the metadata. See `Ash.Type` for more. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`constraints`](#actions-read-metadata-constraints){: #actions-read-metadata-constraints } | `keyword` | `[]` | Type constraints on the metadata |
|
|
| [`description`](#actions-read-metadata-description){: #actions-read-metadata-description } | `String.t` | | An optional description for the metadata. |
|
|
| [`allow_nil?`](#actions-read-metadata-allow_nil?){: #actions-read-metadata-allow_nil? } | `boolean` | `true` | Whether or not the metadata may return `nil` |
|
|
| [`default`](#actions-read-metadata-default){: #actions-read-metadata-default } | `any` | | The default value for the metadata to take. It can be a zero argument function e.g `&MyMod.my_fun/0` or a value |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Actions.Metadata`
|
|
|
|
## actions.read.filter
|
|
```elixir
|
|
filter filter
|
|
```
|
|
|
|
|
|
Applies a filter. Can use `^arg/1`, `^context/1` and `^actor/1` teplates. Multiple filters are combined with *and*.
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
filter expr(first_name == "fred")
|
|
filter expr(last_name == "weasley" and magician == true)
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`filter`](#actions-read-filter-filter){: #actions-read-filter-filter .spark-required} | `any` | | The filter to apply. Can use `^arg/1`, `^context/1` and `^actor/1` teplates. Multiple filters are combined with *and*. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Dsl.Filter`
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Actions.Read`
|
|
|
|
## actions.update
|
|
```elixir
|
|
update name
|
|
```
|
|
|
|
|
|
Declares a `update` action. For calling this action, see the `Ash.Domain` documentation.
|
|
|
|
|
|
### Nested DSLs
|
|
* [change](#actions-update-change)
|
|
* [validate](#actions-update-validate)
|
|
* [metadata](#actions-update-metadata)
|
|
* [argument](#actions-update-argument)
|
|
|
|
|
|
### Examples
|
|
```
|
|
update :flag_for_review, primary?: true
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#actions-update-name){: #actions-update-name .spark-required} | `atom` | | The name of the action |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`manual`](#actions-update-manual){: #actions-update-manual } | `(any, any -> any) \| module` | | Override the update behavior. Accepts a module or module and opts, or a function that takes the changeset and context. See the [manual actions guide](/documentation/topics/manual-actions.md) for more. |
|
|
| [`require_atomic?`](#actions-update-require_atomic?){: #actions-update-require_atomic? } | `boolean` | `true` | Require that the update be atomic. This means that all changes and validations implement the `atomic` callback. See the guide on atomic updates for more. |
|
|
| [`atomic_upgrade?`](#actions-update-atomic_upgrade?){: #actions-update-atomic_upgrade? } | `boolean` | `false` | If set to `true`, atomic upgrades will be performed. Ignored if `required_atomic?` is `true`. See the update actions guide for more. |
|
|
| [`atomic_upgrade_with`](#actions-update-atomic_upgrade_with){: #actions-update-atomic_upgrade_with } | `:atom \| nil` | | Configure the read action used when performing atomic upgrades. Defaults to the primary read action. |
|
|
| [`primary?`](#actions-update-primary?){: #actions-update-primary? } | `boolean` | `false` | Whether or not this action should be used when no action is specified by the caller. |
|
|
| [`description`](#actions-update-description){: #actions-update-description } | `String.t` | | An optional description for the action |
|
|
| [`transaction?`](#actions-update-transaction?){: #actions-update-transaction? } | `boolean` | | Whether or not the action should be run in transactions. Reads default to false, while create/update/destroy actions default to `true`. |
|
|
| [`touches_resources`](#actions-update-touches_resources){: #actions-update-touches_resources } | `list(atom)` | | A list of resources that the action may touch, used when building transactions. |
|
|
| [`accept`](#actions-update-accept){: #actions-update-accept } | `atom \| list(atom) \| :*` | | The list of attributes to accept. Use `:*` to accept all public attributes. |
|
|
| [`require_attributes`](#actions-update-require_attributes){: #actions-update-require_attributes } | `list(atom)` | | A list of attributes that would normally `allow_nil?`, to require for this action. No need to include attributes that already do not allow nil? |
|
|
| [`allow_nil_input`](#actions-update-allow_nil_input){: #actions-update-allow_nil_input } | `list(atom)` | | A list of attributes that would normally be required, but should not be for this action. They will still be validated just before the data layer step. |
|
|
| [`delay_global_validations?`](#actions-update-delay_global_validations?){: #actions-update-delay_global_validations? } | `boolean` | `false` | If true, global validations will be done in a `before_action` hook, regardless of their configuration on the resource. |
|
|
| [`skip_global_validations?`](#actions-update-skip_global_validations?){: #actions-update-skip_global_validations? } | `boolean` | `false` | If true, global validations will be skipped. Useful for manual actions. |
|
|
| [`error_handler`](#actions-update-error_handler){: #actions-update-error_handler } | `mfa` | | Sets the error handler on the changeset. See `Ash.Changeset.handle_errors/2` for more |
|
|
| [`notifiers`](#actions-update-notifiers){: #actions-update-notifiers } | `list(module)` | | Notifiers that will be called specifically for this action. |
|
|
| [`manual?`](#actions-update-manual?){: #actions-update-manual? } | `boolean` | | Instructs Ash to *skip* the actual update/create/destroy step at the data layer. See the [manual actions guide](/documentation/topics/manual-actions.md) for more. |
|
|
|
|
|
|
## actions.update.change
|
|
```elixir
|
|
change change
|
|
```
|
|
|
|
|
|
A change to be applied to the changeset.
|
|
|
|
See `Ash.Resource.Change` for more.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
change relate_actor(:reporter)
|
|
```
|
|
|
|
```
|
|
change {MyCustomChange, :foo}
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`change`](#actions-update-change-change){: #actions-update-change-change .spark-required} | `(any, any -> any) \| module` | | The module and options for a change. Also accepts a function that takes the changeset and the context. See `Ash.Resource.Change.Builtins` for builtin changes. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`only_when_valid?`](#actions-update-change-only_when_valid?){: #actions-update-change-only_when_valid? } | `boolean` | `false` | If the change should only be run on valid changes. By default, all changes are run unless stated otherwise here. |
|
|
| [`description`](#actions-update-change-description){: #actions-update-change-description } | `String.t` | | An optional description for the change |
|
|
| [`where`](#actions-update-change-where){: #actions-update-change-where } | `(any, any -> any) \| module \| list((any, any -> any) \| module)` | `[]` | Validations that should pass in order for this change to apply. These validations failing will result in this change being ignored. |
|
|
| [`always_atomic?`](#actions-update-change-always_atomic?){: #actions-update-change-always_atomic? } | `boolean` | `false` | By default, changes are only run atomically if all changes will be run atomically or if there is no `change/3` callback defined. Set this to `true` to run it atomically always. |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Change`
|
|
|
|
## actions.update.validate
|
|
```elixir
|
|
validate validation
|
|
```
|
|
|
|
|
|
Declares a validation to be applied to the changeset.
|
|
|
|
See `Ash.Resource.Validation` for more.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
validate changing(:email)
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`validation`](#actions-update-validate-validation){: #actions-update-validate-validation .spark-required} | `(any, any -> any) \| module` | | The module (or module and opts) that implements the `Ash.Resource.Validation` behaviour. Also accepts a function that receives the changeset and its context. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`where`](#actions-update-validate-where){: #actions-update-validate-where } | `(any, any -> any) \| module \| list((any, any -> any) \| module)` | `[]` | Validations that should pass in order for this validation to apply. Any of these validations failing will result in this validation being ignored. |
|
|
| [`only_when_valid?`](#actions-update-validate-only_when_valid?){: #actions-update-validate-only_when_valid? } | `boolean` | `false` | If the validation should only run on valid changes. Useful for expensive validations or validations that depend on valid data. |
|
|
| [`message`](#actions-update-validate-message){: #actions-update-validate-message } | `String.t` | | If provided, overrides any message set by the validation error |
|
|
| [`description`](#actions-update-validate-description){: #actions-update-validate-description } | `String.t` | | An optional description for the validation |
|
|
| [`before_action?`](#actions-update-validate-before_action?){: #actions-update-validate-before_action? } | `boolean` | `false` | If set to `true`, the validation will be run in a before_action hook |
|
|
| [`always_atomic?`](#actions-update-validate-always_atomic?){: #actions-update-validate-always_atomic? } | `boolean` | `false` | By default, validations are only run atomically if all changes will be run atomically or if there is no `validate/2` callback defined. Set this to `true` to run it atomically always. |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Validation`
|
|
|
|
## actions.update.metadata
|
|
```elixir
|
|
metadata name, type
|
|
```
|
|
|
|
|
|
A special kind of attribute that is only added to specific actions. Nothing sets this value, it must be set in a custom
|
|
change after_action hook via `Ash.Resource.put_metadata/3`.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
metadata :api_token, :string, allow_nil?: false
|
|
|
|
```
|
|
|
|
```
|
|
metadata :operation_id, :string, allow_nil?: false
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#actions-update-metadata-name){: #actions-update-metadata-name .spark-required} | `atom` | | The name of the metadata |
|
|
| [`type`](#actions-update-metadata-type){: #actions-update-metadata-type .spark-required} | `any` | | The type of the metadata. See `Ash.Type` for more. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`constraints`](#actions-update-metadata-constraints){: #actions-update-metadata-constraints } | `keyword` | `[]` | Type constraints on the metadata |
|
|
| [`description`](#actions-update-metadata-description){: #actions-update-metadata-description } | `String.t` | | An optional description for the metadata. |
|
|
| [`allow_nil?`](#actions-update-metadata-allow_nil?){: #actions-update-metadata-allow_nil? } | `boolean` | `true` | Whether or not the metadata may return `nil` |
|
|
| [`default`](#actions-update-metadata-default){: #actions-update-metadata-default } | `any` | | The default value for the metadata to take. It can be a zero argument function e.g `&MyMod.my_fun/0` or a value |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Actions.Metadata`
|
|
|
|
## actions.update.argument
|
|
```elixir
|
|
argument name, type
|
|
```
|
|
|
|
|
|
Declares an argument on the action
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
argument :password_confirmation, :string
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#actions-update-argument-name){: #actions-update-argument-name .spark-required} | `atom` | | The name of the argument |
|
|
| [`type`](#actions-update-argument-type){: #actions-update-argument-type .spark-required} | `module` | | The type of the argument. See `Ash.Type` for more. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`description`](#actions-update-argument-description){: #actions-update-argument-description } | `String.t` | | An optional description for the argument. |
|
|
| [`constraints`](#actions-update-argument-constraints){: #actions-update-argument-constraints } | `keyword` | `[]` | Constraints to provide to the type when casting the value. For more information, see `Ash.Type`. |
|
|
| [`allow_nil?`](#actions-update-argument-allow_nil?){: #actions-update-argument-allow_nil? } | `boolean` | `true` | Whether or not the argument value may be nil (or may be not provided). If nil value is given error is raised. |
|
|
| [`public?`](#actions-update-argument-public?){: #actions-update-argument-public? } | `boolean` | `true` | Whether or not the argument should appear in public interfaces |
|
|
| [`sensitive?`](#actions-update-argument-sensitive?){: #actions-update-argument-sensitive? } | `boolean` | `false` | Whether or not the argument value contains sensitive information, like PII. See the [security guide](/documentation/topics/security/sensitive-data.md) for more. |
|
|
| [`default`](#actions-update-argument-default){: #actions-update-argument-default } | `any` | | The default value for the argument to take. It can be a zero argument function e.g `&MyMod.my_fun/0` or a value |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Actions.Argument`
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Actions.Update`
|
|
|
|
## actions.destroy
|
|
```elixir
|
|
destroy name
|
|
```
|
|
|
|
|
|
Declares a `destroy` action. For calling this action, see the `Ash.Domain` documentation.
|
|
|
|
|
|
### Nested DSLs
|
|
* [change](#actions-destroy-change)
|
|
* [validate](#actions-destroy-validate)
|
|
* [metadata](#actions-destroy-metadata)
|
|
* [argument](#actions-destroy-argument)
|
|
|
|
|
|
### Examples
|
|
```
|
|
destroy :soft_delete do
|
|
primary? true
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#actions-destroy-name){: #actions-destroy-name .spark-required} | `atom` | | The name of the action |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`soft?`](#actions-destroy-soft?){: #actions-destroy-soft? } | `boolean` | `false` | If specified, the destroy action behaves as an update internally |
|
|
| [`manual`](#actions-destroy-manual){: #actions-destroy-manual } | `(any, any -> any) \| module` | | Override the update behavior. Accepts a module or module and opts, or a function that takes the changeset and context. See the [manual actions guide](/documentation/topics/manual-actions.md) for more. |
|
|
| [`require_atomic?`](#actions-destroy-require_atomic?){: #actions-destroy-require_atomic? } | `boolean` | `true` | Require that the update be atomic. Only relevant if `soft?` is set to `true`. This means that all changes and validations implement the `atomic` callback. See the guide on atomic updates for more. |
|
|
| [`atomic_upgrade?`](#actions-destroy-atomic_upgrade?){: #actions-destroy-atomic_upgrade? } | `boolean` | `false` | If set to `true`, atomic upgrades will be performed. See the update actions guide for more. |
|
|
| [`atomic_upgrade_with`](#actions-destroy-atomic_upgrade_with){: #actions-destroy-atomic_upgrade_with } | `:atom \| nil` | | Configure the read action used when performing atomic upgrades. Defaults to the primary read action. |
|
|
| [`primary?`](#actions-destroy-primary?){: #actions-destroy-primary? } | `boolean` | `false` | Whether or not this action should be used when no action is specified by the caller. |
|
|
| [`description`](#actions-destroy-description){: #actions-destroy-description } | `String.t` | | An optional description for the action |
|
|
| [`transaction?`](#actions-destroy-transaction?){: #actions-destroy-transaction? } | `boolean` | | Whether or not the action should be run in transactions. Reads default to false, while create/update/destroy actions default to `true`. |
|
|
| [`touches_resources`](#actions-destroy-touches_resources){: #actions-destroy-touches_resources } | `list(atom)` | | A list of resources that the action may touch, used when building transactions. |
|
|
| [`accept`](#actions-destroy-accept){: #actions-destroy-accept } | `atom \| list(atom) \| :*` | | The list of attributes to accept. Use `:*` to accept all public attributes. |
|
|
| [`require_attributes`](#actions-destroy-require_attributes){: #actions-destroy-require_attributes } | `list(atom)` | | A list of attributes that would normally `allow_nil?`, to require for this action. No need to include attributes that already do not allow nil? |
|
|
| [`allow_nil_input`](#actions-destroy-allow_nil_input){: #actions-destroy-allow_nil_input } | `list(atom)` | | A list of attributes that would normally be required, but should not be for this action. They will still be validated just before the data layer step. |
|
|
| [`delay_global_validations?`](#actions-destroy-delay_global_validations?){: #actions-destroy-delay_global_validations? } | `boolean` | `false` | If true, global validations will be done in a `before_action` hook, regardless of their configuration on the resource. |
|
|
| [`skip_global_validations?`](#actions-destroy-skip_global_validations?){: #actions-destroy-skip_global_validations? } | `boolean` | `false` | If true, global validations will be skipped. Useful for manual actions. |
|
|
| [`error_handler`](#actions-destroy-error_handler){: #actions-destroy-error_handler } | `mfa` | | Sets the error handler on the changeset. See `Ash.Changeset.handle_errors/2` for more |
|
|
| [`notifiers`](#actions-destroy-notifiers){: #actions-destroy-notifiers } | `list(module)` | | Notifiers that will be called specifically for this action. |
|
|
| [`manual?`](#actions-destroy-manual?){: #actions-destroy-manual? } | `boolean` | | Instructs Ash to *skip* the actual update/create/destroy step at the data layer. See the [manual actions guide](/documentation/topics/manual-actions.md) for more. |
|
|
|
|
|
|
## actions.destroy.change
|
|
```elixir
|
|
change change
|
|
```
|
|
|
|
|
|
A change to be applied to the changeset.
|
|
|
|
See `Ash.Resource.Change` for more.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
change relate_actor(:reporter)
|
|
```
|
|
|
|
```
|
|
change {MyCustomChange, :foo}
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`change`](#actions-destroy-change-change){: #actions-destroy-change-change .spark-required} | `(any, any -> any) \| module` | | The module and options for a change. Also accepts a function that takes the changeset and the context. See `Ash.Resource.Change.Builtins` for builtin changes. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`only_when_valid?`](#actions-destroy-change-only_when_valid?){: #actions-destroy-change-only_when_valid? } | `boolean` | `false` | If the change should only be run on valid changes. By default, all changes are run unless stated otherwise here. |
|
|
| [`description`](#actions-destroy-change-description){: #actions-destroy-change-description } | `String.t` | | An optional description for the change |
|
|
| [`where`](#actions-destroy-change-where){: #actions-destroy-change-where } | `(any, any -> any) \| module \| list((any, any -> any) \| module)` | `[]` | Validations that should pass in order for this change to apply. These validations failing will result in this change being ignored. |
|
|
| [`always_atomic?`](#actions-destroy-change-always_atomic?){: #actions-destroy-change-always_atomic? } | `boolean` | `false` | By default, changes are only run atomically if all changes will be run atomically or if there is no `change/3` callback defined. Set this to `true` to run it atomically always. |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Change`
|
|
|
|
## actions.destroy.validate
|
|
```elixir
|
|
validate validation
|
|
```
|
|
|
|
|
|
Declares a validation to be applied to the changeset.
|
|
|
|
See `Ash.Resource.Validation` for more.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
validate changing(:email)
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`validation`](#actions-destroy-validate-validation){: #actions-destroy-validate-validation .spark-required} | `(any, any -> any) \| module` | | The module (or module and opts) that implements the `Ash.Resource.Validation` behaviour. Also accepts a function that receives the changeset and its context. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`where`](#actions-destroy-validate-where){: #actions-destroy-validate-where } | `(any, any -> any) \| module \| list((any, any -> any) \| module)` | `[]` | Validations that should pass in order for this validation to apply. Any of these validations failing will result in this validation being ignored. |
|
|
| [`only_when_valid?`](#actions-destroy-validate-only_when_valid?){: #actions-destroy-validate-only_when_valid? } | `boolean` | `false` | If the validation should only run on valid changes. Useful for expensive validations or validations that depend on valid data. |
|
|
| [`message`](#actions-destroy-validate-message){: #actions-destroy-validate-message } | `String.t` | | If provided, overrides any message set by the validation error |
|
|
| [`description`](#actions-destroy-validate-description){: #actions-destroy-validate-description } | `String.t` | | An optional description for the validation |
|
|
| [`before_action?`](#actions-destroy-validate-before_action?){: #actions-destroy-validate-before_action? } | `boolean` | `false` | If set to `true`, the validation will be run in a before_action hook |
|
|
| [`always_atomic?`](#actions-destroy-validate-always_atomic?){: #actions-destroy-validate-always_atomic? } | `boolean` | `false` | By default, validations are only run atomically if all changes will be run atomically or if there is no `validate/2` callback defined. Set this to `true` to run it atomically always. |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Validation`
|
|
|
|
## actions.destroy.metadata
|
|
```elixir
|
|
metadata name, type
|
|
```
|
|
|
|
|
|
A special kind of attribute that is only added to specific actions. Nothing sets this value, it must be set in a custom
|
|
change after_action hook via `Ash.Resource.put_metadata/3`.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
metadata :api_token, :string, allow_nil?: false
|
|
|
|
```
|
|
|
|
```
|
|
metadata :operation_id, :string, allow_nil?: false
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#actions-destroy-metadata-name){: #actions-destroy-metadata-name .spark-required} | `atom` | | The name of the metadata |
|
|
| [`type`](#actions-destroy-metadata-type){: #actions-destroy-metadata-type .spark-required} | `any` | | The type of the metadata. See `Ash.Type` for more. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`constraints`](#actions-destroy-metadata-constraints){: #actions-destroy-metadata-constraints } | `keyword` | `[]` | Type constraints on the metadata |
|
|
| [`description`](#actions-destroy-metadata-description){: #actions-destroy-metadata-description } | `String.t` | | An optional description for the metadata. |
|
|
| [`allow_nil?`](#actions-destroy-metadata-allow_nil?){: #actions-destroy-metadata-allow_nil? } | `boolean` | `true` | Whether or not the metadata may return `nil` |
|
|
| [`default`](#actions-destroy-metadata-default){: #actions-destroy-metadata-default } | `any` | | The default value for the metadata to take. It can be a zero argument function e.g `&MyMod.my_fun/0` or a value |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Actions.Metadata`
|
|
|
|
## actions.destroy.argument
|
|
```elixir
|
|
argument name, type
|
|
```
|
|
|
|
|
|
Declares an argument on the action
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
argument :password_confirmation, :string
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#actions-destroy-argument-name){: #actions-destroy-argument-name .spark-required} | `atom` | | The name of the argument |
|
|
| [`type`](#actions-destroy-argument-type){: #actions-destroy-argument-type .spark-required} | `module` | | The type of the argument. See `Ash.Type` for more. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`description`](#actions-destroy-argument-description){: #actions-destroy-argument-description } | `String.t` | | An optional description for the argument. |
|
|
| [`constraints`](#actions-destroy-argument-constraints){: #actions-destroy-argument-constraints } | `keyword` | `[]` | Constraints to provide to the type when casting the value. For more information, see `Ash.Type`. |
|
|
| [`allow_nil?`](#actions-destroy-argument-allow_nil?){: #actions-destroy-argument-allow_nil? } | `boolean` | `true` | Whether or not the argument value may be nil (or may be not provided). If nil value is given error is raised. |
|
|
| [`public?`](#actions-destroy-argument-public?){: #actions-destroy-argument-public? } | `boolean` | `true` | Whether or not the argument should appear in public interfaces |
|
|
| [`sensitive?`](#actions-destroy-argument-sensitive?){: #actions-destroy-argument-sensitive? } | `boolean` | `false` | Whether or not the argument value contains sensitive information, like PII. See the [security guide](/documentation/topics/security/sensitive-data.md) for more. |
|
|
| [`default`](#actions-destroy-argument-default){: #actions-destroy-argument-default } | `any` | | The default value for the argument to take. It can be a zero argument function e.g `&MyMod.my_fun/0` or a value |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Actions.Argument`
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Actions.Destroy`
|
|
|
|
|
|
|
|
|
|
## code_interface
|
|
Functions that will be defined on the resource. See the [code interface guide](/documentation/topics/resources/code-interfaces.md) for more.
|
|
|
|
|
|
### Nested DSLs
|
|
* [define](#code_interface-define)
|
|
* [define_calculation](#code_interface-define_calculation)
|
|
|
|
|
|
### Examples
|
|
```
|
|
code_interface do
|
|
define :create_user, action: :create
|
|
define :get_user_by_id, action: :get_by_id, args: [:id], get?: true
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`domain`](#code_interface-domain){: #code_interface-domain } | `module` | `false` | Use the provided Domain instead of the resources configured domain when calling actions. |
|
|
| [`define?`](#code_interface-define?){: #code_interface-define? } | `boolean` | | Whether or not to define the code interface in the resource. |
|
|
|
|
|
|
|
|
## code_interface.define
|
|
```elixir
|
|
define name
|
|
```
|
|
|
|
|
|
Defines a function with the corresponding name and arguments. See the [code interface guide](/documentation/topics/resources/code-interfaces.md) for more.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
define :get_user_by_id, action: :get_by_id, args: [:id], get?: true
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#code_interface-define-name){: #code_interface-define-name .spark-required} | `atom` | | The name of the function that will be defined |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`action`](#code_interface-define-action){: #code_interface-define-action } | `atom` | | The name of the action that will be called. Defaults to the same name as the function. |
|
|
| [`args`](#code_interface-define-args){: #code_interface-define-args } | `list(atom \| {:optional, atom})` | | Map specific arguments to named inputs. Can provide any argument/attributes that the action allows. |
|
|
| [`not_found_error?`](#code_interface-define-not_found_error?){: #code_interface-define-not_found_error? } | `boolean` | `true` | If the action or interface is configured with `get?: true`, this determines whether or not an error is raised or `nil` is returned. |
|
|
| [`require_reference?`](#code_interface-define-require_reference?){: #code_interface-define-require_reference? } | `boolean` | `true` | For update and destroy actions, require a resource or identifier to be passed in as the first argument. Not relevant for other action types. |
|
|
| [`get?`](#code_interface-define-get?){: #code_interface-define-get? } | `boolean` | `false` | Expects to only receive a single result from a read action or a bulk update/destroy, and returns a single result instead of a list. Sets `require_reference?` to false automatically. |
|
|
| [`get_by`](#code_interface-define-get_by){: #code_interface-define-get_by } | `atom \| list(atom)` | | Takes a list of fields and adds those fields as arguments, which will then be used to filter. Sets `get?` to true and `require_reference?` to false automatically. Adds filters for read, update and destroy actions, replacing the `record` first argument. |
|
|
| [`get_by_identity`](#code_interface-define-get_by_identity){: #code_interface-define-get_by_identity } | `atom` | | Takes an identity, gets its field list, and performs the same logic as `get_by` with those fields. Adds filters for read, update and destroy actions, replacing the `record` first argument. |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Interface`
|
|
|
|
## code_interface.define_calculation
|
|
```elixir
|
|
define_calculation name
|
|
```
|
|
|
|
|
|
Defines a function with the corresponding name and arguments, that evaluates a calculation. Use `:_record` to take an instance of a record. See the [code interface guide](/documentation/topics/resources/code-interfaces.md) for more.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
define_calculation :referral_link, args: [:id]
|
|
```
|
|
|
|
```
|
|
define_calculation :referral_link, args: [{:arg, :id}, {:ref, :id}]
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#code_interface-define_calculation-name){: #code_interface-define_calculation-name .spark-required} | `atom` | | The name of the function that will be defined |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`calculation`](#code_interface-define_calculation-calculation){: #code_interface-define_calculation-calculation } | `atom` | | The name of the calculation that will be evaluated. Defaults to the same name as the function. |
|
|
| [`args`](#code_interface-define_calculation-args){: #code_interface-define_calculation-args } | `any` | `[]` | Supply field or argument values referenced by the calculation, in the form of :name, `{:arg, :name}` and/or `{:ref, :name}`. See the [code interface guide](/documentation/topics/resources/code-interfaces.md) for more. |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.CalculationInterface`
|
|
|
|
|
|
|
|
|
|
## resource
|
|
General resource configuration
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
resource do
|
|
description "A description of this resource"
|
|
base_filter [is_nil: :deleted_at]
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`description`](#resource-description){: #resource-description } | `String.t` | | A human readable description of the resource, to be used in generated documentation |
|
|
| [`base_filter`](#resource-base_filter){: #resource-base_filter } | `any` | | A filter statement to be applied to any queries on the resource |
|
|
| [`default_context`](#resource-default_context){: #resource-default_context } | `any` | | Default context to apply to any queries/changesets generated for this resource. |
|
|
| [`trace_name`](#resource-trace_name){: #resource-trace_name } | `String.t` | | The name to use in traces. Defaults to the short_name stringified. See the [monitoring guide](/documentation/topics/monitoring.md) for more. |
|
|
| [`short_name`](#resource-short_name){: #resource-short_name } | `atom` | | A short identifier for the resource, which should be unique. See the [monitoring guide](/documentation/topics/monitoring.md) for more. |
|
|
| [`plural_name`](#resource-plural_name){: #resource-plural_name } | `atom` | | A pluralized version of the resource short_name. May be used by generators or automated tooling. |
|
|
| [`require_primary_key?`](#resource-require_primary_key?){: #resource-require_primary_key? } | `boolean` | `true` | Allow the resource to be used without any primary key fields. Warning: this option is experimental, and should not be used unless you know what you're doing. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## identities
|
|
Unique identifiers for the resource
|
|
|
|
|
|
### Nested DSLs
|
|
* [identity](#identities-identity)
|
|
|
|
|
|
### Examples
|
|
```
|
|
identities do
|
|
identity :full_name, [:first_name, :last_name]
|
|
identity :email, [:email]
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## identities.identity
|
|
```elixir
|
|
identity name, keys
|
|
```
|
|
|
|
|
|
Represents a unique constraint on the resource.
|
|
|
|
See the [identities guide](/documentation/topics/resources/identities.md) for more.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
identity :name, [:name]
|
|
```
|
|
|
|
```
|
|
identity :full_name, [:first_name, :last_name]
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#identities-identity-name){: #identities-identity-name .spark-required} | `atom` | | The name of the identity. |
|
|
| [`keys`](#identities-identity-keys){: #identities-identity-keys .spark-required} | `atom \| list(atom)` | | The names of the attributes that uniquely identify this resource. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`where`](#identities-identity-where){: #identities-identity-where } | `any` | | A filter that expresses only matching records are unique on the provided keys. Ignored on embedded resources. |
|
|
| [`nils_distinct?`](#identities-identity-nils_distinct?){: #identities-identity-nils_distinct? } | `boolean` | `true` | Whether or not `nil` values are considered always distinct from eachother. `nil` values won't conflict with eachother unless you set this option to `false`. |
|
|
| [`eager_check?`](#identities-identity-eager_check?){: #identities-identity-eager_check? } | `boolean` | `false` | Whether or not this identity is validated to be unique at validation time. |
|
|
| [`eager_check_with`](#identities-identity-eager_check_with){: #identities-identity-eager_check_with } | `module` | | Validates that the unique identity provided is unique at validation time, outside of any transactions, using the domain module provided. Will default to resource's domain. |
|
|
| [`pre_check?`](#identities-identity-pre_check?){: #identities-identity-pre_check? } | `boolean` | `false` | Whether or not this identity is validated to be unique in a before_action hook. |
|
|
| [`pre_check_with`](#identities-identity-pre_check_with){: #identities-identity-pre_check_with } | `module` | | Validates that the unique identity provided is unique in a before_action hook. |
|
|
| [`description`](#identities-identity-description){: #identities-identity-description } | `String.t` | | An optional description for the identity |
|
|
| [`message`](#identities-identity-message){: #identities-identity-message } | `String.t` | | An error message to use when the unique identity would be violated |
|
|
| [`all_tenants?`](#identities-identity-all_tenants?){: #identities-identity-all_tenants? } | `boolean` | `false` | Whether or not this identity is unique across all tenants. If the resource is not multitenant, has no effect. |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Identity`
|
|
|
|
|
|
|
|
|
|
## changes
|
|
Declare changes that occur on create/update/destroy actions against the resource
|
|
|
|
See `Ash.Resource.Change` for more.
|
|
|
|
|
|
### Nested DSLs
|
|
* [change](#changes-change)
|
|
|
|
|
|
### Examples
|
|
```
|
|
changes do
|
|
change {Mod, [foo: :bar]}
|
|
change set_context(%{some: :context})
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## changes.change
|
|
```elixir
|
|
change change
|
|
```
|
|
|
|
|
|
A change to be applied to the changeset.
|
|
|
|
See `Ash.Resource.Change` for more.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
change relate_actor(:reporter)
|
|
```
|
|
|
|
```
|
|
change {MyCustomChange, :foo}
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`change`](#changes-change-change){: #changes-change-change .spark-required} | `(any, any -> any) \| module` | | The module and options for a change. Also accepts a function that takes the changeset and the context. See `Ash.Resource.Change.Builtins` for builtin changes. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`on`](#changes-change-on){: #changes-change-on } | `:create \| :update \| :destroy \| list(:create \| :update \| :destroy)` | `[:create, :update]` | The action types the change should run on. Destroy actions are omitted by default as most changes don't make sense for a destroy. |
|
|
| [`only_when_valid?`](#changes-change-only_when_valid?){: #changes-change-only_when_valid? } | `boolean` | `false` | If the change should only be run on valid changes. By default, all changes are run unless stated otherwise here. |
|
|
| [`description`](#changes-change-description){: #changes-change-description } | `String.t` | | An optional description for the change |
|
|
| [`where`](#changes-change-where){: #changes-change-where } | `(any, any -> any) \| module \| list((any, any -> any) \| module)` | `[]` | Validations that should pass in order for this change to apply. These validations failing will result in this change being ignored. |
|
|
| [`always_atomic?`](#changes-change-always_atomic?){: #changes-change-always_atomic? } | `boolean` | `false` | By default, changes are only run atomically if all changes will be run atomically or if there is no `change/3` callback defined. Set this to `true` to run it atomically always. |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Change`
|
|
|
|
|
|
|
|
|
|
## preparations
|
|
Declare preparations that occur on all read actions for a given resource
|
|
|
|
|
|
### Nested DSLs
|
|
* [prepare](#preparations-prepare)
|
|
|
|
|
|
### Examples
|
|
```
|
|
preparations do
|
|
prepare {Mod, [foo: :bar]}
|
|
prepare set_context(%{some: :context})
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## preparations.prepare
|
|
```elixir
|
|
prepare preparation
|
|
```
|
|
|
|
|
|
Declares a preparation, which can be used to prepare a query for a read action.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
prepare build(sort: [:foo, :bar])
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`preparation`](#preparations-prepare-preparation){: #preparations-prepare-preparation .spark-required} | `(any, any -> any) \| module` | | The module and options for a preparation. Also accepts functions take the query and the context. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Preparation`
|
|
|
|
|
|
|
|
|
|
## validations
|
|
Declare validations prior to performing actions against the resource
|
|
|
|
|
|
### Nested DSLs
|
|
* [validate](#validations-validate)
|
|
|
|
|
|
### Examples
|
|
```
|
|
validations do
|
|
validate {Mod, [foo: :bar]}
|
|
validate at_least_one_of_present([:first_name, :last_name])
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## validations.validate
|
|
```elixir
|
|
validate validation
|
|
```
|
|
|
|
|
|
Declares a validation for creates and updates.
|
|
|
|
See `Ash.Resource.Change` for more.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
validate {Mod, [foo: :bar]}
|
|
```
|
|
|
|
```
|
|
validate at_least_one_of_present([:first_name, :last_name])
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`validation`](#validations-validate-validation){: #validations-validate-validation .spark-required} | `(any, any -> any) \| module` | | The module (or module and opts) that implements the `Ash.Resource.Validation` behaviour. Also accepts a function that receives the changeset and its context. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`where`](#validations-validate-where){: #validations-validate-where } | `(any, any -> any) \| module \| list((any, any -> any) \| module)` | `[]` | Validations that should pass in order for this validation to apply. Any of these validations failing will result in this validation being ignored. |
|
|
| [`on`](#validations-validate-on){: #validations-validate-on } | `:create \| :update \| :destroy \| list(:create \| :update \| :destroy)` | `[:create, :update]` | The action types the validation should run on. Many validations don't make sense in the context of deletion, so by default it is not included. |
|
|
| [`only_when_valid?`](#validations-validate-only_when_valid?){: #validations-validate-only_when_valid? } | `boolean` | `false` | If the validation should only run on valid changes. Useful for expensive validations or validations that depend on valid data. |
|
|
| [`message`](#validations-validate-message){: #validations-validate-message } | `String.t` | | If provided, overrides any message set by the validation error |
|
|
| [`description`](#validations-validate-description){: #validations-validate-description } | `String.t` | | An optional description for the validation |
|
|
| [`before_action?`](#validations-validate-before_action?){: #validations-validate-before_action? } | `boolean` | `false` | If set to `true`, the validation will be run in a before_action hook |
|
|
| [`always_atomic?`](#validations-validate-always_atomic?){: #validations-validate-always_atomic? } | `boolean` | `false` | By default, validations are only run atomically if all changes will be run atomically or if there is no `validate/2` callback defined. Set this to `true` to run it atomically always. |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Validation`
|
|
|
|
|
|
|
|
|
|
## aggregates
|
|
Declare named aggregates on the resource.
|
|
|
|
These are aggregates that can be loaded only by name using `Ash.Query.load/2`.
|
|
They are also available as top level fields on the resource.
|
|
|
|
See the [aggregates guide](/documentation/topics/resources/aggregates.md) for more.
|
|
|
|
|
|
### Nested DSLs
|
|
* [count](#aggregates-count)
|
|
* join_filter
|
|
* [exists](#aggregates-exists)
|
|
* join_filter
|
|
* [first](#aggregates-first)
|
|
* join_filter
|
|
* [sum](#aggregates-sum)
|
|
* join_filter
|
|
* [list](#aggregates-list)
|
|
* join_filter
|
|
* [max](#aggregates-max)
|
|
* join_filter
|
|
* [min](#aggregates-min)
|
|
* join_filter
|
|
* [avg](#aggregates-avg)
|
|
* join_filter
|
|
* [custom](#aggregates-custom)
|
|
* join_filter
|
|
|
|
|
|
### Examples
|
|
```
|
|
aggregates do
|
|
count :assigned_ticket_count, :reported_tickets do
|
|
filter [active: true]
|
|
end
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## aggregates.count
|
|
```elixir
|
|
count name, relationship_path
|
|
```
|
|
|
|
|
|
Declares a named count aggregate on the resource
|
|
|
|
Supports `filter`, but not `sort` (because that wouldn't affect the count)
|
|
|
|
See the [aggregates guide](/documentation/topics/resources/aggregates.md) for more.
|
|
|
|
|
|
### Nested DSLs
|
|
* [join_filter](#aggregates-count-join_filter)
|
|
|
|
|
|
### Examples
|
|
```
|
|
count :assigned_ticket_count, :assigned_tickets do
|
|
filter [active: true]
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#aggregates-count-name){: #aggregates-count-name .spark-required} | `atom` | | The field to place the aggregate in |
|
|
| [`relationship_path`](#aggregates-count-relationship_path){: #aggregates-count-relationship_path .spark-required} | `atom \| list(atom)` | | The relationship or relationship path to use for the aggregate |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`kind`](#aggregates-count-kind){: #aggregates-count-kind .spark-required} | `:count \| :first \| :sum \| :list \| :avg \| :max \| :min \| :exists \| :custom \| {:custom, module}` | | The kind of the aggregate |
|
|
| [`uniq?`](#aggregates-count-uniq?){: #aggregates-count-uniq? } | `boolean` | `false` | Whether or not to count unique values only |
|
|
| [`read_action`](#aggregates-count-read_action){: #aggregates-count-read_action } | `atom` | | The read action to use when building the aggregate. Defaults to the primary read action. Keep in mind this action must not have any required arguments. |
|
|
| [`field`](#aggregates-count-field){: #aggregates-count-field } | `atom` | | The field to aggregate. Defaults to the first field in the primary key of the resource |
|
|
| [`filter`](#aggregates-count-filter){: #aggregates-count-filter } | `any` | `[]` | A filter to apply to the aggregate |
|
|
| [`description`](#aggregates-count-description){: #aggregates-count-description } | `String.t` | | An optional description for the aggregate |
|
|
| [`default`](#aggregates-count-default){: #aggregates-count-default } | `any` | | A default value to use in cases where nil would be used. Count defaults to `0`. |
|
|
| [`public?`](#aggregates-count-public?){: #aggregates-count-public? } | `boolean` | `false` | Whether or not the aggregate will appear in public interfaces |
|
|
| [`filterable?`](#aggregates-count-filterable?){: #aggregates-count-filterable? } | `boolean \| :simple_equality` | `true` | Whether or not the aggregate should be usable in filters. |
|
|
| [`sortable?`](#aggregates-count-sortable?){: #aggregates-count-sortable? } | `boolean` | `true` | Whether or not the aggregate should be usable in sorts. |
|
|
| [`sensitive?`](#aggregates-count-sensitive?){: #aggregates-count-sensitive? } | `boolean` | `false` | Whether or not the aggregate should be considered sensitive. |
|
|
| [`authorize?`](#aggregates-count-authorize?){: #aggregates-count-authorize? } | `boolean` | `true` | Whether or not the aggregate query should authorize based on the target action, if the parent query is authorized. Requires filter checks on the target action. |
|
|
|
|
|
|
## aggregates.count.join_filter
|
|
```elixir
|
|
join_filter relationship_path, filter
|
|
```
|
|
|
|
|
|
Declares a join filter on an aggregate. See the aggregates guide for more.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
join_filter [:comments, :author], expr(active == true)
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`relationship_path`](#aggregates-count-join_filter-relationship_path){: #aggregates-count-join_filter-relationship_path } | `atom \| list(atom)` | | The relationship path on which to apply the join filter |
|
|
| [`filter`](#aggregates-count-join_filter-filter){: #aggregates-count-join_filter-filter } | `any` | | The filter to apply. Can be an expression or a filter template. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Aggregate.JoinFilter`
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Aggregate`
|
|
|
|
## aggregates.exists
|
|
```elixir
|
|
exists name, relationship_path
|
|
```
|
|
|
|
|
|
Declares a named `exists` aggregate on the resource
|
|
|
|
Supports `filter`, but not `sort` (because that wouldn't affect if something exists)
|
|
|
|
See the [aggregates guide](/documentation/topics/resources/aggregates.md) for more.
|
|
|
|
|
|
### Nested DSLs
|
|
* [join_filter](#aggregates-exists-join_filter)
|
|
|
|
|
|
### Examples
|
|
```
|
|
exists :has_ticket, :assigned_tickets
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#aggregates-exists-name){: #aggregates-exists-name .spark-required} | `atom` | | The field to place the aggregate in |
|
|
| [`relationship_path`](#aggregates-exists-relationship_path){: #aggregates-exists-relationship_path .spark-required} | `atom \| list(atom)` | | The relationship or relationship path to use for the aggregate |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`kind`](#aggregates-exists-kind){: #aggregates-exists-kind .spark-required} | `:count \| :first \| :sum \| :list \| :avg \| :max \| :min \| :exists \| :custom \| {:custom, module}` | | The kind of the aggregate |
|
|
| [`read_action`](#aggregates-exists-read_action){: #aggregates-exists-read_action } | `atom` | | The read action to use when building the aggregate. Defaults to the primary read action. Keep in mind this action must not have any required arguments. |
|
|
| [`filter`](#aggregates-exists-filter){: #aggregates-exists-filter } | `any` | `[]` | A filter to apply to the aggregate |
|
|
| [`description`](#aggregates-exists-description){: #aggregates-exists-description } | `String.t` | | An optional description for the aggregate |
|
|
| [`default`](#aggregates-exists-default){: #aggregates-exists-default } | `any` | | A default value to use in cases where nil would be used. Count defaults to `0`. |
|
|
| [`public?`](#aggregates-exists-public?){: #aggregates-exists-public? } | `boolean` | `false` | Whether or not the aggregate will appear in public interfaces |
|
|
| [`filterable?`](#aggregates-exists-filterable?){: #aggregates-exists-filterable? } | `boolean \| :simple_equality` | `true` | Whether or not the aggregate should be usable in filters. |
|
|
| [`sortable?`](#aggregates-exists-sortable?){: #aggregates-exists-sortable? } | `boolean` | `true` | Whether or not the aggregate should be usable in sorts. |
|
|
| [`sensitive?`](#aggregates-exists-sensitive?){: #aggregates-exists-sensitive? } | `boolean` | `false` | Whether or not the aggregate should be considered sensitive. |
|
|
| [`authorize?`](#aggregates-exists-authorize?){: #aggregates-exists-authorize? } | `boolean` | `true` | Whether or not the aggregate query should authorize based on the target action, if the parent query is authorized. Requires filter checks on the target action. |
|
|
|
|
|
|
## aggregates.exists.join_filter
|
|
```elixir
|
|
join_filter relationship_path, filter
|
|
```
|
|
|
|
|
|
Declares a join filter on an aggregate. See the aggregates guide for more.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
join_filter [:comments, :author], expr(active == true)
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`relationship_path`](#aggregates-exists-join_filter-relationship_path){: #aggregates-exists-join_filter-relationship_path } | `atom \| list(atom)` | | The relationship path on which to apply the join filter |
|
|
| [`filter`](#aggregates-exists-join_filter-filter){: #aggregates-exists-join_filter-filter } | `any` | | The filter to apply. Can be an expression or a filter template. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Aggregate.JoinFilter`
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Aggregate`
|
|
|
|
## aggregates.first
|
|
```elixir
|
|
first name, relationship_path, field
|
|
```
|
|
|
|
|
|
Declares a named `first` aggregate on the resource
|
|
|
|
First aggregates return the first value of the related record
|
|
that matches. Supports both `filter` and `sort`.
|
|
|
|
See the [aggregates guide](/documentation/topics/resources/aggregates.md) for more.
|
|
|
|
|
|
### Nested DSLs
|
|
* [join_filter](#aggregates-first-join_filter)
|
|
|
|
|
|
### Examples
|
|
```
|
|
first :first_assigned_ticket_subject, :assigned_tickets, :subject do
|
|
filter [active: true]
|
|
sort [:subject]
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#aggregates-first-name){: #aggregates-first-name .spark-required} | `atom` | | The field to place the aggregate in |
|
|
| [`relationship_path`](#aggregates-first-relationship_path){: #aggregates-first-relationship_path .spark-required} | `atom \| list(atom)` | | The relationship or relationship path to use for the aggregate |
|
|
| [`field`](#aggregates-first-field){: #aggregates-first-field } | `atom` | | The field to aggregate. Defaults to the first field in the primary key of the resource |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`kind`](#aggregates-first-kind){: #aggregates-first-kind .spark-required} | `:count \| :first \| :sum \| :list \| :avg \| :max \| :min \| :exists \| :custom \| {:custom, module}` | | The kind of the aggregate |
|
|
| [`include_nil?`](#aggregates-first-include_nil?){: #aggregates-first-include_nil? } | `boolean` | | Whether or not to include `nil` values in the aggregate. Only relevant for `list` and `first` aggregates. |
|
|
| [`read_action`](#aggregates-first-read_action){: #aggregates-first-read_action } | `atom` | | The read action to use when building the aggregate. Defaults to the primary read action. Keep in mind this action must not have any required arguments. |
|
|
| [`filter`](#aggregates-first-filter){: #aggregates-first-filter } | `any` | `[]` | A filter to apply to the aggregate |
|
|
| [`sort`](#aggregates-first-sort){: #aggregates-first-sort } | `any` | | A sort to be applied to the aggregate |
|
|
| [`description`](#aggregates-first-description){: #aggregates-first-description } | `String.t` | | An optional description for the aggregate |
|
|
| [`default`](#aggregates-first-default){: #aggregates-first-default } | `any` | | A default value to use in cases where nil would be used. Count defaults to `0`. |
|
|
| [`public?`](#aggregates-first-public?){: #aggregates-first-public? } | `boolean` | `false` | Whether or not the aggregate will appear in public interfaces |
|
|
| [`filterable?`](#aggregates-first-filterable?){: #aggregates-first-filterable? } | `boolean \| :simple_equality` | `true` | Whether or not the aggregate should be usable in filters. |
|
|
| [`sortable?`](#aggregates-first-sortable?){: #aggregates-first-sortable? } | `boolean` | `true` | Whether or not the aggregate should be usable in sorts. |
|
|
| [`sensitive?`](#aggregates-first-sensitive?){: #aggregates-first-sensitive? } | `boolean` | `false` | Whether or not the aggregate should be considered sensitive. |
|
|
| [`authorize?`](#aggregates-first-authorize?){: #aggregates-first-authorize? } | `boolean` | `true` | Whether or not the aggregate query should authorize based on the target action, if the parent query is authorized. Requires filter checks on the target action. |
|
|
|
|
|
|
## aggregates.first.join_filter
|
|
```elixir
|
|
join_filter relationship_path, filter
|
|
```
|
|
|
|
|
|
Declares a join filter on an aggregate. See the aggregates guide for more.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
join_filter [:comments, :author], expr(active == true)
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`relationship_path`](#aggregates-first-join_filter-relationship_path){: #aggregates-first-join_filter-relationship_path } | `atom \| list(atom)` | | The relationship path on which to apply the join filter |
|
|
| [`filter`](#aggregates-first-join_filter-filter){: #aggregates-first-join_filter-filter } | `any` | | The filter to apply. Can be an expression or a filter template. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Aggregate.JoinFilter`
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Aggregate`
|
|
|
|
## aggregates.sum
|
|
```elixir
|
|
sum name, relationship_path, field
|
|
```
|
|
|
|
|
|
Declares a named `sum` aggregate on the resource
|
|
|
|
Supports `filter`, but not `sort` (because that wouldn't affect the sum)
|
|
|
|
See the [aggregates guide](/documentation/topics/resources/aggregates.md) for more.
|
|
|
|
|
|
### Nested DSLs
|
|
* [join_filter](#aggregates-sum-join_filter)
|
|
|
|
|
|
### Examples
|
|
```
|
|
sum :assigned_ticket_price_sum, :assigned_tickets, :price do
|
|
filter [active: true]
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#aggregates-sum-name){: #aggregates-sum-name .spark-required} | `atom` | | The field to place the aggregate in |
|
|
| [`relationship_path`](#aggregates-sum-relationship_path){: #aggregates-sum-relationship_path .spark-required} | `atom \| list(atom)` | | The relationship or relationship path to use for the aggregate |
|
|
| [`field`](#aggregates-sum-field){: #aggregates-sum-field } | `atom` | | The field to aggregate. Defaults to the first field in the primary key of the resource |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`kind`](#aggregates-sum-kind){: #aggregates-sum-kind .spark-required} | `:count \| :first \| :sum \| :list \| :avg \| :max \| :min \| :exists \| :custom \| {:custom, module}` | | The kind of the aggregate |
|
|
| [`read_action`](#aggregates-sum-read_action){: #aggregates-sum-read_action } | `atom` | | The read action to use when building the aggregate. Defaults to the primary read action. Keep in mind this action must not have any required arguments. |
|
|
| [`filter`](#aggregates-sum-filter){: #aggregates-sum-filter } | `any` | `[]` | A filter to apply to the aggregate |
|
|
| [`description`](#aggregates-sum-description){: #aggregates-sum-description } | `String.t` | | An optional description for the aggregate |
|
|
| [`default`](#aggregates-sum-default){: #aggregates-sum-default } | `any` | | A default value to use in cases where nil would be used. Count defaults to `0`. |
|
|
| [`public?`](#aggregates-sum-public?){: #aggregates-sum-public? } | `boolean` | `false` | Whether or not the aggregate will appear in public interfaces |
|
|
| [`filterable?`](#aggregates-sum-filterable?){: #aggregates-sum-filterable? } | `boolean \| :simple_equality` | `true` | Whether or not the aggregate should be usable in filters. |
|
|
| [`sortable?`](#aggregates-sum-sortable?){: #aggregates-sum-sortable? } | `boolean` | `true` | Whether or not the aggregate should be usable in sorts. |
|
|
| [`sensitive?`](#aggregates-sum-sensitive?){: #aggregates-sum-sensitive? } | `boolean` | `false` | Whether or not the aggregate should be considered sensitive. |
|
|
| [`authorize?`](#aggregates-sum-authorize?){: #aggregates-sum-authorize? } | `boolean` | `true` | Whether or not the aggregate query should authorize based on the target action, if the parent query is authorized. Requires filter checks on the target action. |
|
|
|
|
|
|
## aggregates.sum.join_filter
|
|
```elixir
|
|
join_filter relationship_path, filter
|
|
```
|
|
|
|
|
|
Declares a join filter on an aggregate. See the aggregates guide for more.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
join_filter [:comments, :author], expr(active == true)
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`relationship_path`](#aggregates-sum-join_filter-relationship_path){: #aggregates-sum-join_filter-relationship_path } | `atom \| list(atom)` | | The relationship path on which to apply the join filter |
|
|
| [`filter`](#aggregates-sum-join_filter-filter){: #aggregates-sum-join_filter-filter } | `any` | | The filter to apply. Can be an expression or a filter template. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Aggregate.JoinFilter`
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Aggregate`
|
|
|
|
## aggregates.list
|
|
```elixir
|
|
list name, relationship_path, field
|
|
```
|
|
|
|
|
|
Declares a named `list` aggregate on the resource.
|
|
|
|
A list aggregate selects the list of all values for the given field
|
|
and relationship combination.
|
|
|
|
See the [aggregates guide](/documentation/topics/resources/aggregates.md) for more.
|
|
|
|
|
|
### Nested DSLs
|
|
* [join_filter](#aggregates-list-join_filter)
|
|
|
|
|
|
### Examples
|
|
```
|
|
list :assigned_ticket_prices, :assigned_tickets, :price do
|
|
filter [active: true]
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#aggregates-list-name){: #aggregates-list-name .spark-required} | `atom` | | The field to place the aggregate in |
|
|
| [`relationship_path`](#aggregates-list-relationship_path){: #aggregates-list-relationship_path .spark-required} | `atom \| list(atom)` | | The relationship or relationship path to use for the aggregate |
|
|
| [`field`](#aggregates-list-field){: #aggregates-list-field } | `atom` | | The field to aggregate. Defaults to the first field in the primary key of the resource |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`kind`](#aggregates-list-kind){: #aggregates-list-kind .spark-required} | `:count \| :first \| :sum \| :list \| :avg \| :max \| :min \| :exists \| :custom \| {:custom, module}` | | The kind of the aggregate |
|
|
| [`uniq?`](#aggregates-list-uniq?){: #aggregates-list-uniq? } | `boolean` | `false` | Whether or not to count unique values only |
|
|
| [`read_action`](#aggregates-list-read_action){: #aggregates-list-read_action } | `atom` | | The read action to use when building the aggregate. Defaults to the primary read action. Keep in mind this action must not have any required arguments. |
|
|
| [`filter`](#aggregates-list-filter){: #aggregates-list-filter } | `any` | `[]` | A filter to apply to the aggregate |
|
|
| [`sort`](#aggregates-list-sort){: #aggregates-list-sort } | `any` | | A sort to be applied to the aggregate |
|
|
| [`description`](#aggregates-list-description){: #aggregates-list-description } | `String.t` | | An optional description for the aggregate |
|
|
| [`default`](#aggregates-list-default){: #aggregates-list-default } | `any` | | A default value to use in cases where nil would be used. Count defaults to `0`. |
|
|
| [`public?`](#aggregates-list-public?){: #aggregates-list-public? } | `boolean` | `false` | Whether or not the aggregate will appear in public interfaces |
|
|
| [`filterable?`](#aggregates-list-filterable?){: #aggregates-list-filterable? } | `boolean \| :simple_equality` | `true` | Whether or not the aggregate should be usable in filters. |
|
|
| [`sortable?`](#aggregates-list-sortable?){: #aggregates-list-sortable? } | `boolean` | `true` | Whether or not the aggregate should be usable in sorts. |
|
|
| [`sensitive?`](#aggregates-list-sensitive?){: #aggregates-list-sensitive? } | `boolean` | `false` | Whether or not the aggregate should be considered sensitive. |
|
|
| [`authorize?`](#aggregates-list-authorize?){: #aggregates-list-authorize? } | `boolean` | `true` | Whether or not the aggregate query should authorize based on the target action, if the parent query is authorized. Requires filter checks on the target action. |
|
|
|
|
|
|
## aggregates.list.join_filter
|
|
```elixir
|
|
join_filter relationship_path, filter
|
|
```
|
|
|
|
|
|
Declares a join filter on an aggregate. See the aggregates guide for more.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
join_filter [:comments, :author], expr(active == true)
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`relationship_path`](#aggregates-list-join_filter-relationship_path){: #aggregates-list-join_filter-relationship_path } | `atom \| list(atom)` | | The relationship path on which to apply the join filter |
|
|
| [`filter`](#aggregates-list-join_filter-filter){: #aggregates-list-join_filter-filter } | `any` | | The filter to apply. Can be an expression or a filter template. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Aggregate.JoinFilter`
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Aggregate`
|
|
|
|
## aggregates.max
|
|
```elixir
|
|
max name, relationship_path, field
|
|
```
|
|
|
|
|
|
Declares a named `max` aggregate on the resource
|
|
|
|
Supports `filter`, but not `sort` (because that wouldn't affect the max)
|
|
|
|
See the [aggregates guide](/documentation/topics/resources/aggregates.md) for more.
|
|
|
|
|
|
### Nested DSLs
|
|
* [join_filter](#aggregates-max-join_filter)
|
|
|
|
|
|
### Examples
|
|
```
|
|
max :first_assigned_ticket_subject, :assigned_tickets, :severity do
|
|
filter [active: true]
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#aggregates-max-name){: #aggregates-max-name .spark-required} | `atom` | | The field to place the aggregate in |
|
|
| [`relationship_path`](#aggregates-max-relationship_path){: #aggregates-max-relationship_path .spark-required} | `atom \| list(atom)` | | The relationship or relationship path to use for the aggregate |
|
|
| [`field`](#aggregates-max-field){: #aggregates-max-field } | `atom` | | The field to aggregate. Defaults to the first field in the primary key of the resource |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`kind`](#aggregates-max-kind){: #aggregates-max-kind .spark-required} | `:count \| :first \| :sum \| :list \| :avg \| :max \| :min \| :exists \| :custom \| {:custom, module}` | | The kind of the aggregate |
|
|
| [`read_action`](#aggregates-max-read_action){: #aggregates-max-read_action } | `atom` | | The read action to use when building the aggregate. Defaults to the primary read action. Keep in mind this action must not have any required arguments. |
|
|
| [`filter`](#aggregates-max-filter){: #aggregates-max-filter } | `any` | `[]` | A filter to apply to the aggregate |
|
|
| [`description`](#aggregates-max-description){: #aggregates-max-description } | `String.t` | | An optional description for the aggregate |
|
|
| [`default`](#aggregates-max-default){: #aggregates-max-default } | `any` | | A default value to use in cases where nil would be used. Count defaults to `0`. |
|
|
| [`public?`](#aggregates-max-public?){: #aggregates-max-public? } | `boolean` | `false` | Whether or not the aggregate will appear in public interfaces |
|
|
| [`filterable?`](#aggregates-max-filterable?){: #aggregates-max-filterable? } | `boolean \| :simple_equality` | `true` | Whether or not the aggregate should be usable in filters. |
|
|
| [`sortable?`](#aggregates-max-sortable?){: #aggregates-max-sortable? } | `boolean` | `true` | Whether or not the aggregate should be usable in sorts. |
|
|
| [`sensitive?`](#aggregates-max-sensitive?){: #aggregates-max-sensitive? } | `boolean` | `false` | Whether or not the aggregate should be considered sensitive. |
|
|
| [`authorize?`](#aggregates-max-authorize?){: #aggregates-max-authorize? } | `boolean` | `true` | Whether or not the aggregate query should authorize based on the target action, if the parent query is authorized. Requires filter checks on the target action. |
|
|
|
|
|
|
## aggregates.max.join_filter
|
|
```elixir
|
|
join_filter relationship_path, filter
|
|
```
|
|
|
|
|
|
Declares a join filter on an aggregate. See the aggregates guide for more.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
join_filter [:comments, :author], expr(active == true)
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`relationship_path`](#aggregates-max-join_filter-relationship_path){: #aggregates-max-join_filter-relationship_path } | `atom \| list(atom)` | | The relationship path on which to apply the join filter |
|
|
| [`filter`](#aggregates-max-join_filter-filter){: #aggregates-max-join_filter-filter } | `any` | | The filter to apply. Can be an expression or a filter template. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Aggregate.JoinFilter`
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Aggregate`
|
|
|
|
## aggregates.min
|
|
```elixir
|
|
min name, relationship_path, field
|
|
```
|
|
|
|
|
|
Declares a named `min` aggregate on the resource
|
|
|
|
Supports `filter`, but not `sort` (because that wouldn't affect the min)
|
|
|
|
See the [aggregates guide](/documentation/topics/resources/aggregates.md) for more.
|
|
|
|
|
|
### Nested DSLs
|
|
* [join_filter](#aggregates-min-join_filter)
|
|
|
|
|
|
### Examples
|
|
```
|
|
min :first_assigned_ticket_subject, :assigned_tickets, :severity do
|
|
filter [active: true]
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#aggregates-min-name){: #aggregates-min-name .spark-required} | `atom` | | The field to place the aggregate in |
|
|
| [`relationship_path`](#aggregates-min-relationship_path){: #aggregates-min-relationship_path .spark-required} | `atom \| list(atom)` | | The relationship or relationship path to use for the aggregate |
|
|
| [`field`](#aggregates-min-field){: #aggregates-min-field } | `atom` | | The field to aggregate. Defaults to the first field in the primary key of the resource |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`kind`](#aggregates-min-kind){: #aggregates-min-kind .spark-required} | `:count \| :first \| :sum \| :list \| :avg \| :max \| :min \| :exists \| :custom \| {:custom, module}` | | The kind of the aggregate |
|
|
| [`read_action`](#aggregates-min-read_action){: #aggregates-min-read_action } | `atom` | | The read action to use when building the aggregate. Defaults to the primary read action. Keep in mind this action must not have any required arguments. |
|
|
| [`filter`](#aggregates-min-filter){: #aggregates-min-filter } | `any` | `[]` | A filter to apply to the aggregate |
|
|
| [`description`](#aggregates-min-description){: #aggregates-min-description } | `String.t` | | An optional description for the aggregate |
|
|
| [`default`](#aggregates-min-default){: #aggregates-min-default } | `any` | | A default value to use in cases where nil would be used. Count defaults to `0`. |
|
|
| [`public?`](#aggregates-min-public?){: #aggregates-min-public? } | `boolean` | `false` | Whether or not the aggregate will appear in public interfaces |
|
|
| [`filterable?`](#aggregates-min-filterable?){: #aggregates-min-filterable? } | `boolean \| :simple_equality` | `true` | Whether or not the aggregate should be usable in filters. |
|
|
| [`sortable?`](#aggregates-min-sortable?){: #aggregates-min-sortable? } | `boolean` | `true` | Whether or not the aggregate should be usable in sorts. |
|
|
| [`sensitive?`](#aggregates-min-sensitive?){: #aggregates-min-sensitive? } | `boolean` | `false` | Whether or not the aggregate should be considered sensitive. |
|
|
| [`authorize?`](#aggregates-min-authorize?){: #aggregates-min-authorize? } | `boolean` | `true` | Whether or not the aggregate query should authorize based on the target action, if the parent query is authorized. Requires filter checks on the target action. |
|
|
|
|
|
|
## aggregates.min.join_filter
|
|
```elixir
|
|
join_filter relationship_path, filter
|
|
```
|
|
|
|
|
|
Declares a join filter on an aggregate. See the aggregates guide for more.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
join_filter [:comments, :author], expr(active == true)
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`relationship_path`](#aggregates-min-join_filter-relationship_path){: #aggregates-min-join_filter-relationship_path } | `atom \| list(atom)` | | The relationship path on which to apply the join filter |
|
|
| [`filter`](#aggregates-min-join_filter-filter){: #aggregates-min-join_filter-filter } | `any` | | The filter to apply. Can be an expression or a filter template. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Aggregate.JoinFilter`
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Aggregate`
|
|
|
|
## aggregates.avg
|
|
```elixir
|
|
avg name, relationship_path, field
|
|
```
|
|
|
|
|
|
Declares a named `avg` aggregate on the resource
|
|
|
|
Supports `filter`, but not `sort` (because that wouldn't affect the avg)
|
|
|
|
See the [aggregates guide](/documentation/topics/resources/aggregates.md) for more.
|
|
|
|
|
|
### Nested DSLs
|
|
* [join_filter](#aggregates-avg-join_filter)
|
|
|
|
|
|
### Examples
|
|
```
|
|
avg :assigned_ticket_price_sum, :assigned_tickets, :price do
|
|
filter [active: true]
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#aggregates-avg-name){: #aggregates-avg-name .spark-required} | `atom` | | The field to place the aggregate in |
|
|
| [`relationship_path`](#aggregates-avg-relationship_path){: #aggregates-avg-relationship_path .spark-required} | `atom \| list(atom)` | | The relationship or relationship path to use for the aggregate |
|
|
| [`field`](#aggregates-avg-field){: #aggregates-avg-field } | `atom` | | The field to aggregate. Defaults to the first field in the primary key of the resource |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`kind`](#aggregates-avg-kind){: #aggregates-avg-kind .spark-required} | `:count \| :first \| :sum \| :list \| :avg \| :max \| :min \| :exists \| :custom \| {:custom, module}` | | The kind of the aggregate |
|
|
| [`read_action`](#aggregates-avg-read_action){: #aggregates-avg-read_action } | `atom` | | The read action to use when building the aggregate. Defaults to the primary read action. Keep in mind this action must not have any required arguments. |
|
|
| [`filter`](#aggregates-avg-filter){: #aggregates-avg-filter } | `any` | `[]` | A filter to apply to the aggregate |
|
|
| [`description`](#aggregates-avg-description){: #aggregates-avg-description } | `String.t` | | An optional description for the aggregate |
|
|
| [`default`](#aggregates-avg-default){: #aggregates-avg-default } | `any` | | A default value to use in cases where nil would be used. Count defaults to `0`. |
|
|
| [`public?`](#aggregates-avg-public?){: #aggregates-avg-public? } | `boolean` | `false` | Whether or not the aggregate will appear in public interfaces |
|
|
| [`filterable?`](#aggregates-avg-filterable?){: #aggregates-avg-filterable? } | `boolean \| :simple_equality` | `true` | Whether or not the aggregate should be usable in filters. |
|
|
| [`sortable?`](#aggregates-avg-sortable?){: #aggregates-avg-sortable? } | `boolean` | `true` | Whether or not the aggregate should be usable in sorts. |
|
|
| [`sensitive?`](#aggregates-avg-sensitive?){: #aggregates-avg-sensitive? } | `boolean` | `false` | Whether or not the aggregate should be considered sensitive. |
|
|
| [`authorize?`](#aggregates-avg-authorize?){: #aggregates-avg-authorize? } | `boolean` | `true` | Whether or not the aggregate query should authorize based on the target action, if the parent query is authorized. Requires filter checks on the target action. |
|
|
|
|
|
|
## aggregates.avg.join_filter
|
|
```elixir
|
|
join_filter relationship_path, filter
|
|
```
|
|
|
|
|
|
Declares a join filter on an aggregate. See the aggregates guide for more.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
join_filter [:comments, :author], expr(active == true)
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`relationship_path`](#aggregates-avg-join_filter-relationship_path){: #aggregates-avg-join_filter-relationship_path } | `atom \| list(atom)` | | The relationship path on which to apply the join filter |
|
|
| [`filter`](#aggregates-avg-join_filter-filter){: #aggregates-avg-join_filter-filter } | `any` | | The filter to apply. Can be an expression or a filter template. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Aggregate.JoinFilter`
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Aggregate`
|
|
|
|
## aggregates.custom
|
|
```elixir
|
|
custom name, relationship_path, type
|
|
```
|
|
|
|
|
|
Declares a named `custom` aggregate on the resource
|
|
|
|
Supports `filter` and `sort`.
|
|
|
|
Custom aggregates provide an `implementation` which must implement data layer specific callbacks.
|
|
|
|
See the relevant data layer documentation and the [aggregates guide](/documentation/topics/resources/aggregates.md) for more.
|
|
|
|
|
|
### Nested DSLs
|
|
* [join_filter](#aggregates-custom-join_filter)
|
|
|
|
|
|
### Examples
|
|
```
|
|
custom :author_names, :authors, :string do
|
|
implementation {StringAgg, delimiter: ","}
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#aggregates-custom-name){: #aggregates-custom-name .spark-required} | `atom` | | The field to place the aggregate in |
|
|
| [`relationship_path`](#aggregates-custom-relationship_path){: #aggregates-custom-relationship_path .spark-required} | `atom \| list(atom)` | | The relationship or relationship path to use for the aggregate |
|
|
| [`type`](#aggregates-custom-type){: #aggregates-custom-type .spark-required} | `module` | | The type of the value returned by the aggregate |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`implementation`](#aggregates-custom-implementation){: #aggregates-custom-implementation .spark-required} | `module` | | The module that implements the relevant data layer callbacks |
|
|
| [`kind`](#aggregates-custom-kind){: #aggregates-custom-kind .spark-required} | `:count \| :first \| :sum \| :list \| :avg \| :max \| :min \| :exists \| :custom \| {:custom, module}` | | The kind of the aggregate |
|
|
| [`read_action`](#aggregates-custom-read_action){: #aggregates-custom-read_action } | `atom` | | The read action to use when building the aggregate. Defaults to the primary read action. Keep in mind this action must not have any required arguments. |
|
|
| [`field`](#aggregates-custom-field){: #aggregates-custom-field } | `atom` | | The field to aggregate. Defaults to the first field in the primary key of the resource |
|
|
| [`filter`](#aggregates-custom-filter){: #aggregates-custom-filter } | `any` | `[]` | A filter to apply to the aggregate |
|
|
| [`sort`](#aggregates-custom-sort){: #aggregates-custom-sort } | `any` | | A sort to be applied to the aggregate |
|
|
| [`description`](#aggregates-custom-description){: #aggregates-custom-description } | `String.t` | | An optional description for the aggregate |
|
|
| [`default`](#aggregates-custom-default){: #aggregates-custom-default } | `any` | | A default value to use in cases where nil would be used. Count defaults to `0`. |
|
|
| [`public?`](#aggregates-custom-public?){: #aggregates-custom-public? } | `boolean` | `false` | Whether or not the aggregate will appear in public interfaces |
|
|
| [`filterable?`](#aggregates-custom-filterable?){: #aggregates-custom-filterable? } | `boolean \| :simple_equality` | `true` | Whether or not the aggregate should be usable in filters. |
|
|
| [`sortable?`](#aggregates-custom-sortable?){: #aggregates-custom-sortable? } | `boolean` | `true` | Whether or not the aggregate should be usable in sorts. |
|
|
| [`sensitive?`](#aggregates-custom-sensitive?){: #aggregates-custom-sensitive? } | `boolean` | `false` | Whether or not the aggregate should be considered sensitive. |
|
|
| [`authorize?`](#aggregates-custom-authorize?){: #aggregates-custom-authorize? } | `boolean` | `true` | Whether or not the aggregate query should authorize based on the target action, if the parent query is authorized. Requires filter checks on the target action. |
|
|
|
|
|
|
## aggregates.custom.join_filter
|
|
```elixir
|
|
join_filter relationship_path, filter
|
|
```
|
|
|
|
|
|
Declares a join filter on an aggregate. See the aggregates guide for more.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
join_filter [:comments, :author], expr(active == true)
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`relationship_path`](#aggregates-custom-join_filter-relationship_path){: #aggregates-custom-join_filter-relationship_path } | `atom \| list(atom)` | | The relationship path on which to apply the join filter |
|
|
| [`filter`](#aggregates-custom-join_filter-filter){: #aggregates-custom-join_filter-filter } | `any` | | The filter to apply. Can be an expression or a filter template. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Aggregate.JoinFilter`
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Aggregate`
|
|
|
|
|
|
|
|
|
|
## calculations
|
|
Declare named calculations on the resource.
|
|
|
|
These are calculations that can be loaded only by name using `Ash.Query.load/2`.
|
|
They are also available as top level fields on the resource.
|
|
|
|
See the [calculations guide](/documentation/topics/resources/calculations.md) for more.
|
|
|
|
|
|
### Nested DSLs
|
|
* [calculate](#calculations-calculate)
|
|
* argument
|
|
|
|
|
|
### Examples
|
|
```
|
|
calculations do
|
|
calculate :full_name, :string, MyApp.MyResource.FullName
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## calculations.calculate
|
|
```elixir
|
|
calculate name, type, calculation \\ nil
|
|
```
|
|
|
|
|
|
Declares a named calculation on the resource.
|
|
|
|
Takes a module that must adopt the `Ash.Resource.Calculation` behaviour. See that module
|
|
for more information.
|
|
|
|
To ensure that the necessary fields are selected:
|
|
|
|
1.) Specifying the `select` option on a calculation in the resource.
|
|
2.) Define a `select/2` callback in the calculation module
|
|
3.) Set `always_select?` on the attribute in question
|
|
|
|
See the [calculations guide](/documentation/topics/resources/calculations.md) for more.
|
|
|
|
|
|
### Nested DSLs
|
|
* [argument](#calculations-calculate-argument)
|
|
|
|
|
|
### Examples
|
|
`Ash.Resource.Calculation` implementation example:
|
|
```
|
|
calculate :full_name, :string, {MyApp.FullName, keys: [:first_name, :last_name]}, select: [:first_name, :last_name]
|
|
```
|
|
|
|
`expr/1` example:
|
|
```
|
|
calculate :full_name, :string, expr(first_name <> " " <> last_name)
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#calculations-calculate-name){: #calculations-calculate-name .spark-required} | `atom` | | The field name to use for the calculation value |
|
|
| [`type`](#calculations-calculate-type){: #calculations-calculate-type .spark-required} | `any` | | The type of the calculation. See `Ash.Type` for more. |
|
|
| [`calculation`](#calculations-calculate-calculation){: #calculations-calculate-calculation .spark-required} | `(any, any -> any) \| module \| any` | | The `module`, `{module, opts}` or `expr(...)` to use for the calculation. Also accepts a function that takes *a single record* and produces the result. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`constraints`](#calculations-calculate-constraints){: #calculations-calculate-constraints } | `keyword` | `[]` | Constraints to provide to the type. See `Ash.Type` for more. |
|
|
| [`description`](#calculations-calculate-description){: #calculations-calculate-description } | `String.t` | | An optional description for the calculation |
|
|
| [`public?`](#calculations-calculate-public?){: #calculations-calculate-public? } | `boolean` | `false` | Whether or not the calculation will appear in public interfaces. |
|
|
| [`sensitive?`](#calculations-calculate-sensitive?){: #calculations-calculate-sensitive? } | `boolean` | `false` | Whether or not references to the calculation will be considered sensitive. |
|
|
| [`load`](#calculations-calculate-load){: #calculations-calculate-load } | `any` | `[]` | A load statement to be applied if the calculation is used. |
|
|
| [`allow_nil?`](#calculations-calculate-allow_nil?){: #calculations-calculate-allow_nil? } | `boolean` | `true` | Whether or not the calculation can return nil. |
|
|
| [`filterable?`](#calculations-calculate-filterable?){: #calculations-calculate-filterable? } | `boolean \| :simple_equality` | `true` | Whether or not the calculation should be usable in filters. |
|
|
| [`sortable?`](#calculations-calculate-sortable?){: #calculations-calculate-sortable? } | `boolean` | `true` | Whether or not the calculation can be referenced in sorts. |
|
|
|
|
|
|
## calculations.calculate.argument
|
|
```elixir
|
|
argument name, type
|
|
```
|
|
|
|
|
|
An argument to be passed into the calculation's arguments map
|
|
|
|
See the [calculations guide](/documentation/topics/resources/calculations.md) for more.
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
argument :params, :map do
|
|
default %{}
|
|
end
|
|
|
|
```
|
|
|
|
```
|
|
argument :retries, :integer do
|
|
allow_nil? false
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
### Arguments
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`name`](#calculations-calculate-argument-name){: #calculations-calculate-argument-name .spark-required} | `atom` | | The name of the argument |
|
|
| [`type`](#calculations-calculate-argument-type){: #calculations-calculate-argument-type .spark-required} | `module` | | The type of the argument. See `Ash.Type` for more. |
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`default`](#calculations-calculate-argument-default){: #calculations-calculate-argument-default } | `(-> any) \| mfa \| any` | | A default value to use for the argument if not provided |
|
|
| [`allow_nil?`](#calculations-calculate-argument-allow_nil?){: #calculations-calculate-argument-allow_nil? } | `boolean` | `true` | Whether or not the argument value may be nil (or may be not provided) |
|
|
| [`allow_expr?`](#calculations-calculate-argument-allow_expr?){: #calculations-calculate-argument-allow_expr? } | `boolean` | `false` | Allow passing expressions as argument values. Expressions cannot be type validated. |
|
|
| [`constraints`](#calculations-calculate-argument-constraints){: #calculations-calculate-argument-constraints } | `keyword` | `[]` | Constraints to provide to the type when casting the value. See the type's documentation and `Ash.Type` for more. |
|
|
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Calculation.Argument`
|
|
|
|
|
|
|
|
|
|
### Introspection
|
|
|
|
Target: `Ash.Resource.Calculation`
|
|
|
|
|
|
|
|
|
|
## multitenancy
|
|
Options for configuring the multitenancy behavior of a resource.
|
|
|
|
To specify a tenant, use `Ash.Query.set_tenant/2` or
|
|
`Ash.Changeset.set_tenant/2` before passing it to an operation.
|
|
|
|
See the [multitenancy guide](/documentation/topics/advanced/multitenancy.md)
|
|
|
|
|
|
|
|
|
|
### Examples
|
|
```
|
|
multitenancy do
|
|
strategy :attribute
|
|
attribute :organization_id
|
|
global? true
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Options
|
|
|
|
| Name | Type | Default | Docs |
|
|
|------|------|---------|------|
|
|
| [`strategy`](#multitenancy-strategy){: #multitenancy-strategy } | `:context \| :attribute` | `:context` | Determine if multitenancy is performed with attribute filters or using data layer features. |
|
|
| [`attribute`](#multitenancy-attribute){: #multitenancy-attribute } | `atom` | | If using the `attribute` strategy, the attribute to use, e.g `org_id` |
|
|
| [`global?`](#multitenancy-global?){: #multitenancy-global? } | `boolean` | `false` | Whether or not the data may be accessed without setting a tenant. For example, with attribute multitenancy, this allows accessing without filtering by the tenant attribute. |
|
|
| [`parse_attribute`](#multitenancy-parse_attribute){: #multitenancy-parse_attribute } | `mfa` | `{Ash.Resource.Dsl, :identity, []}` | An mfa ({module, function, args}) pointing to a function that takes a tenant and returns the attribute value |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<style type="text/css">.spark-required::after { content: "*"; color: red !important; }</style>
|