# DSL: Ash.Reactor `Ash.Reactor` is a [`Reactor`](https://hex.pm/packages/reactor) extension which provides steps for working with Ash resources and actions. See the [Ash Reactor Guide](https://hexdocs.pm/ash/reactor.html) for more information. ## ash Ash-related configuration for the `Ash.Reactor` extension ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`default_domain`](#ash-default_domain){: #ash-default_domain } | `module` | | A domain to use by default when calling actions | ## reactor.action ```elixir action name, resource, action \\ nil ``` Declares a step that will call a generic action on a resource. > #### Undo behaviour {: .tip} > > This step has three different modes of undo. > > * `never` - The result of the action is never undone. This is the default. > * `always` - The `undo_action` will always be called. > * `outside_transaction` - The `undo_action` will not be called when running inside a `transaction` block, but will be otherwise. ### Nested DSLs * [actor](#reactor-action-actor) * [inputs](#reactor-action-inputs) * [tenant](#reactor-action-tenant) * [wait_for](#reactor-action-wait_for) ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`name`](#reactor-action-name){: #reactor-action-name .spark-required} | `atom` | | A unique name for the step. | | [`resource`](#reactor-action-resource){: #reactor-action-resource .spark-required} | `module` | | The resource to call the action on. | | [`action`](#reactor-action-action){: #reactor-action-action } | `atom` | | The name of the action to call on the resource. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`domain`](#reactor-action-domain){: #reactor-action-domain } | `module` | | The Domain to use when calling the action. Defaults to the Domain set on the resource or in the `ash` section. | | [`async?`](#reactor-action-async?){: #reactor-action-async? } | `boolean` | `true` | When set to true the step will be executed asynchronously via Reactor's `TaskSupervisor`. | | [`authorize?`](#reactor-action-authorize?){: #reactor-action-authorize? } | `boolean \| nil` | | Explicitly enable or disable authorization for the action. | | [`description`](#reactor-action-description){: #reactor-action-description } | `String.t` | | A description for the step | | [`undo_action`](#reactor-action-undo_action){: #reactor-action-undo_action } | `atom` | | The name of the action to call on the resource when the step is to be undone. | | [`undo`](#reactor-action-undo){: #reactor-action-undo } | `:always \| :never \| :outside_transaction` | `:never` | How to handle undoing this action | ## reactor.action.actor ```elixir actor source ``` Specifies the action actor ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`source`](#reactor-action-actor-source){: #reactor-action-actor-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the actor. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`transform`](#reactor-action-actor-transform){: #reactor-action-actor-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the actor before it is passed to the action. | ### Introspection Target: `Ash.Reactor.Dsl.Actor` ## reactor.action.inputs ```elixir inputs template ``` Specify the inputs for an action ### Examples ``` inputs %{ author: result(:get_user), title: input(:title), body: input(:body) } ``` ``` inputs(author: result(:get_user)) ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`template`](#reactor-action-inputs-template){: #reactor-action-inputs-template .spark-required} | `%{optional(atom) => Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value} \| keyword(Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value)` | | | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`transform`](#reactor-action-inputs-transform){: #reactor-action-inputs-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which will transform the inputs before executing the action. | ### Introspection Target: `Ash.Reactor.Dsl.Inputs` ## reactor.action.tenant ```elixir tenant source ``` Specifies the action tenant ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`source`](#reactor-action-tenant-source){: #reactor-action-tenant-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the tenant. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`transform`](#reactor-action-tenant-transform){: #reactor-action-tenant-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the tenant before it is passed to the action. | ### Introspection Target: `Ash.Reactor.Dsl.Tenant` ## reactor.action.wait_for ```elixir wait_for names ``` Wait for the named step to complete before allowing this one to start. Desugars to `argument :_, result(step_to_wait_for)` ### Examples ``` wait_for :create_user ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`names`](#reactor-action-wait_for-names){: #reactor-action-wait_for-names .spark-required} | `atom \| list(atom)` | | The name of the step to wait for. | ### Introspection Target: `Reactor.Dsl.WaitFor` ### Introspection Target: `Ash.Reactor.Dsl.Action` ## reactor.ash_step ```elixir ash_step name, impl \\ nil ``` Specifies a Ash.Reactor step. This is basically a wrapper around `Reactor.step`, in order to handle any returned notifications from the run step/function. See the `Reactor.Step` behaviour for more information. ### Nested DSLs * [argument](#reactor-ash_step-argument) * [wait_for](#reactor-ash_step-wait_for) ### Examples ``` ash_step :create_post, MyApp.CreatePostStep do argument :title, input(:title) end ``` ``` ash_step :create_post do argument :title, input(:title) run fn %{title: title}, _ -> MyApp.Post.create(title, return_notifications?: true) end end ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`name`](#reactor-ash_step-name){: #reactor-ash_step-name .spark-required} | `atom` | | A unique name for the step. Used when choosing the return value of the Reactor and for arguments into other steps. | | [`impl`](#reactor-ash_step-impl){: #reactor-ash_step-impl } | `module \| nil` | | A module that implements the `Reactor.Step` behaviour that provides the implementation. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`run`](#reactor-ash_step-run){: #reactor-ash_step-run } | `(any -> any) \| mfa \| (any, any -> any) \| mfa` | | Provide an anonymous function which implements the `run/3` callback. Cannot be provided at the same time as the `impl` argument. | | [`undo`](#reactor-ash_step-undo){: #reactor-ash_step-undo } | `(any -> any) \| mfa \| (any, any -> any) \| mfa \| (any, any, any -> any) \| mfa` | | Provide an anonymous function which implements the `undo/4` callback. Cannot be provided at the same time as the `impl` argument. | | [`compensate`](#reactor-ash_step-compensate){: #reactor-ash_step-compensate } | `(any -> any) \| mfa \| (any, any -> any) \| mfa \| (any, any, any -> any) \| mfa` | | Provide an anonymous function which implements the `undo/4` callback. Cannot be provided at the same time as the `impl` argument. | | [`max_retries`](#reactor-ash_step-max_retries){: #reactor-ash_step-max_retries } | `:infinity \| non_neg_integer` | `:infinity` | The maximum number of times that the step can be retried before failing. Only used when the result of the `compensate/4` callback is `:retry`. | | [`async?`](#reactor-ash_step-async?){: #reactor-ash_step-async? } | `boolean` | `true` | When set to true the step will be executed asynchronously via Reactor's `TaskSupervisor`. | | [`transform`](#reactor-ash_step-transform){: #reactor-ash_step-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the entire argument map before it is passed to the step. | ## reactor.ash_step.argument ```elixir argument name, source \\ nil ``` Specifies an argument to a Reactor step. Each argument is a value which is either the result of another step, or an input value. Individual arguments can be transformed with an arbitrary function before being passed to any steps. ### Examples ``` argument :name, input(:name) ``` ``` argument :year, input(:date, [:year]) ``` ``` argument :user, result(:create_user) ``` ``` argument :user_id, result(:create_user) do transform & &1.id end ``` ``` argument :user_id, result(:create_user, [:id]) ``` ``` argument :three, value(3) ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`name`](#reactor-ash_step-argument-name){: #reactor-ash_step-argument-name .spark-required} | `atom` | | The name of the argument which will be used as the key in the `arguments` map passed to the implementation. | | [`source`](#reactor-ash_step-argument-source){: #reactor-ash_step-argument-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the argument. See `Reactor.Dsl.Argument` for more information. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`transform`](#reactor-ash_step-argument-transform){: #reactor-ash_step-argument-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the argument before it is passed to the step. | ### Introspection Target: `Reactor.Dsl.Argument` ## reactor.ash_step.wait_for ```elixir wait_for names ``` Wait for the named step to complete before allowing this one to start. Desugars to `argument :_, result(step_to_wait_for)` ### Examples ``` wait_for :create_user ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`names`](#reactor-ash_step-wait_for-names){: #reactor-ash_step-wait_for-names .spark-required} | `atom \| list(atom)` | | The name of the step to wait for. | ### Introspection Target: `Reactor.Dsl.WaitFor` ### Introspection Target: `Ash.Reactor.Dsl.AshStep` ## reactor.bulk_create ```elixir bulk_create name, resource, action \\ nil ``` Declares a step which will call a create action on a resource with a collection of inputs. > ### Check the docs! {: .warning} > > Make sure to thoroughly read and understand the documentation in `Ash.bulk_create/4` before using. Read each option and note the default values. By default, bulk creates don't return records or errors, and don't emit notifications. Caveats/differences from `Ash.bulk_create/4`: 1. `max_concurrency` specifies the number of tasks that Ash will start to process batches, and has no effect on Reactor concurrency targets. It's could be possible to create a very large number of processes if a number of steps are running bulk actions with a high degree of concurrency. 2. Setting `notify?` to `true` will cause both `notify?` and `return_notifications?` to be set to true in the underlying call to `Ash.bulk_create/4`. Notifications will then be managed by the `Ash.Reactor.Notifications` Reactor middleware. 3. If you specify an undo action it must be a generic action which takes the bulk result as it's only argument. > #### Undo behaviour {: .tip} > > This step has three different modes of undo. > > * `never` - The result of the action is never undone. This is the default. > * `always` - The `undo_action` will always be called. > * `outside_transaction` - The `undo_action` will not be called when running inside a `transaction` block, but will be otherwise. ### Nested DSLs * [actor](#reactor-bulk_create-actor) * [tenant](#reactor-bulk_create-tenant) * [wait_for](#reactor-bulk_create-wait_for) ### Examples ``` bulk_create :create_posts, MyApp.Post, :create do initial input(:titles) actor result(:get_user) tenant result(:get_organisation, [:id]) end ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`name`](#reactor-bulk_create-name){: #reactor-bulk_create-name .spark-required} | `atom` | | A unique name for the step. | | [`resource`](#reactor-bulk_create-resource){: #reactor-bulk_create-resource .spark-required} | `module` | | The resource to call the action on. | | [`action`](#reactor-bulk_create-action){: #reactor-bulk_create-action } | `atom` | | The name of the action to call on the resource. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`initial`](#reactor-bulk_create-initial){: #reactor-bulk_create-initial .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | A collection of inputs to pass to the create action. Must implement the `Enumerable` protocol. | | [`assume_casted?`](#reactor-bulk_create-assume_casted?){: #reactor-bulk_create-assume_casted? } | `boolean` | `false` | Whether or not to cast attributes and arguments as input. This is an optimization for cases where the input is already casted and/or not in need of casting | | [`authorize_changeset_with`](#reactor-bulk_create-authorize_changeset_with){: #reactor-bulk_create-authorize_changeset_with } | `:filter \| :error` | `:filter` | If set to `:error`, instead of filtering unauthorized changes, unauthorized changes will raise an appropriate forbidden error | | [`authorize_query_with`](#reactor-bulk_create-authorize_query_with){: #reactor-bulk_create-authorize_query_with } | `:filter \| :error` | `:filter` | If set to `:error`, instead of filtering unauthorized query results, unauthorized query results will raise an appropriate forbidden error | | [`batch_size`](#reactor-bulk_create-batch_size){: #reactor-bulk_create-batch_size } | `nil \| pos_integer` | | The number of records to include in each batch. Defaults to the `default_limit` or `max_page_size` of the action, or 100. | | [`load`](#reactor-bulk_create-load){: #reactor-bulk_create-load } | `atom \| list(atom)` | `[]` | A load statement to apply to records. Ignored if `return_records?` is not true. | | [`max_concurrency`](#reactor-bulk_create-max_concurrency){: #reactor-bulk_create-max_concurrency } | `non_neg_integer` | `0` | If set to a value greater than 0, up to that many tasks will be started to run batches asynchronously. | | [`notification_metadata`](#reactor-bulk_create-notification_metadata){: #reactor-bulk_create-notification_metadata } | `map \| Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | `%{}` | Metadata to be merged into the metadata field for all notifications sent from this operation. | | [`notify?`](#reactor-bulk_create-notify?){: #reactor-bulk_create-notify? } | `boolean` | `false` | Whether or not to generate any notifications. This may be intensive for large bulk actions. | | [`read_action`](#reactor-bulk_create-read_action){: #reactor-bulk_create-read_action } | `atom` | | The action to use when building the read query. | | [`return_errors?`](#reactor-bulk_create-return_errors?){: #reactor-bulk_create-return_errors? } | `boolean` | `false` | Whether or not to return all of the errors that occur. Defaults to false to account for large inserts. | | [`return_records?`](#reactor-bulk_create-return_records?){: #reactor-bulk_create-return_records? } | `boolean` | `false` | Whether or not to return all of the records that were inserted. Defaults to false to account for large inserts. | | [`return_stream?`](#reactor-bulk_create-return_stream?){: #reactor-bulk_create-return_stream? } | `boolean` | `false` | If set to `true`, instead of an `Ash.BulkResult`, a mixed stream is returned. | | [`rollback_on_error?`](#reactor-bulk_create-rollback_on_error?){: #reactor-bulk_create-rollback_on_error? } | `boolean` | `true` | Whether or not to rollback the transaction on error, if the resource is in a transaction. | | [`select`](#reactor-bulk_create-select){: #reactor-bulk_create-select } | `atom \| list(atom)` | | A select statement to apply to records. Ignored if `return_records?` is not `true`. | | [`skip_unknown_inputs`](#reactor-bulk_create-skip_unknown_inputs){: #reactor-bulk_create-skip_unknown_inputs } | `atom \| String.t \| list(atom \| String.t)` | | A list of inputs that, if provided, will be ignored if they are not recognized by the action. Use `:*` to indicate all unknown keys. | | [`sorted?`](#reactor-bulk_create-sorted?){: #reactor-bulk_create-sorted? } | `boolean` | `false` | Whether or not to sort results by their input position, in cases where `return_records?` is set to `true`. | | [`stop_on_error?`](#reactor-bulk_create-stop_on_error?){: #reactor-bulk_create-stop_on_error? } | `boolean` | `false` | If `true`, the first encountered error will stop the action and be returned. Otherwise, errors will be skipped. | | [`success_state`](#reactor-bulk_create-success_state){: #reactor-bulk_create-success_state } | `:success \| :partial_success` | `:success` | Bulk results can be entirely or partially successful. Chooses the `Ash.BulkResult` state to consider the step a success. | | [`timeout`](#reactor-bulk_create-timeout){: #reactor-bulk_create-timeout } | `timeout` | | If none is provided, the timeout configured on the domain is used (which defaults to `30_000`). | | [`transaction`](#reactor-bulk_create-transaction){: #reactor-bulk_create-transaction } | `:all \| :batch \| false` | `:batch` | Whether or not to wrap the entire execution in a transaction, each batch, or not at all. | | [`upsert_fields`](#reactor-bulk_create-upsert_fields){: #reactor-bulk_create-upsert_fields } | `atom \| list(atom)` | | The fields to upsert. If not set, the action's `upsert_fields` is used. | | [`upsert_identity`](#reactor-bulk_create-upsert_identity){: #reactor-bulk_create-upsert_identity } | `atom` | | The identity to use for the upsert | | [`upsert?`](#reactor-bulk_create-upsert?){: #reactor-bulk_create-upsert? } | `boolean` | `false` | Whether or not this action should be executed as an upsert. | | [`domain`](#reactor-bulk_create-domain){: #reactor-bulk_create-domain } | `module` | | The Domain to use when calling the action. Defaults to the Domain set on the resource or in the `ash` section. | | [`async?`](#reactor-bulk_create-async?){: #reactor-bulk_create-async? } | `boolean` | `true` | When set to true the step will be executed asynchronously via Reactor's `TaskSupervisor`. | | [`authorize?`](#reactor-bulk_create-authorize?){: #reactor-bulk_create-authorize? } | `boolean \| nil` | | Explicitly enable or disable authorization for the action. | | [`description`](#reactor-bulk_create-description){: #reactor-bulk_create-description } | `String.t` | | A description for the step | | [`undo_action`](#reactor-bulk_create-undo_action){: #reactor-bulk_create-undo_action } | `atom` | | The name of the action to call on the resource when the step is to be undone. | | [`undo`](#reactor-bulk_create-undo){: #reactor-bulk_create-undo } | `:always \| :never \| :outside_transaction` | `:never` | How to handle undoing this action | ## reactor.bulk_create.actor ```elixir actor source ``` Specifies the action actor ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`source`](#reactor-bulk_create-actor-source){: #reactor-bulk_create-actor-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the actor. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`transform`](#reactor-bulk_create-actor-transform){: #reactor-bulk_create-actor-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the actor before it is passed to the action. | ### Introspection Target: `Ash.Reactor.Dsl.Actor` ## reactor.bulk_create.tenant ```elixir tenant source ``` Specifies the action tenant ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`source`](#reactor-bulk_create-tenant-source){: #reactor-bulk_create-tenant-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the tenant. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`transform`](#reactor-bulk_create-tenant-transform){: #reactor-bulk_create-tenant-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the tenant before it is passed to the action. | ### Introspection Target: `Ash.Reactor.Dsl.Tenant` ## reactor.bulk_create.wait_for ```elixir wait_for names ``` Wait for the named step to complete before allowing this one to start. Desugars to `argument :_, result(step_to_wait_for)` ### Examples ``` wait_for :create_user ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`names`](#reactor-bulk_create-wait_for-names){: #reactor-bulk_create-wait_for-names .spark-required} | `atom \| list(atom)` | | The name of the step to wait for. | ### Introspection Target: `Reactor.Dsl.WaitFor` ### Introspection Target: `Ash.Reactor.Dsl.BulkCreate` ## reactor.bulk_update ```elixir bulk_update name, resource, action \\ nil ``` Declares a step which will call an update action on a resource with a collection of inputs. > ### Check the docs! {: .warning} > > Make sure to thoroughly read and understand the documentation in `Ash.bulk_update/4` before using. Read each option and note the default values. By default, bulk updates don't return records or errors, and don't emit notifications. Caveats/differences from `Ash.bulk_update/4`: 1. `max_concurrency` specifies the number of tasks that Ash will start to process batches, and has no effect on Reactor concurrency targets. It's could be possible to create a very large number of processes if a number of steps are running bulk actions with a high degree of concurrency. 2. Setting `notify?` to `true` will cause both `notify?` and `return_notifications?` to be set to true in the underlying call to `Ash.bulk_create/4`. Notifications will then be managed by the `Ash.Reactor.Notifications` Reactor middleware. 3. If you specify an undo action it must be a generic action which takes the bulk result as it's only argument. > #### Undo behaviour {: .tip} > > This step has three different modes of undo. > > * `never` - The result of the action is never undone. This is the default. > * `always` - The `undo_action` will always be called. > * `outside_transaction` - The `undo_action` will not be called when running inside a `transaction` block, but will be otherwise. ### Nested DSLs * [actor](#reactor-bulk_update-actor) * [inputs](#reactor-bulk_update-inputs) * [tenant](#reactor-bulk_update-tenant) * [wait_for](#reactor-bulk_update-wait_for) ### Examples ``` bulk_update :publish_posts, MyApp.Post, :publish do initial input(:posts), actor result(:get_user) end ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`name`](#reactor-bulk_update-name){: #reactor-bulk_update-name .spark-required} | `atom` | | A unique name for the step. | | [`resource`](#reactor-bulk_update-resource){: #reactor-bulk_update-resource .spark-required} | `module` | | The resource to call the action on. | | [`action`](#reactor-bulk_update-action){: #reactor-bulk_update-action } | `atom` | | The name of the action to call on the resource. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`initial`](#reactor-bulk_update-initial){: #reactor-bulk_update-initial .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | A collection of inputs to pass to the create action. Must implement the `Enumerable` protocol. | | [`allow_stream_with`](#reactor-bulk_update-allow_stream_with){: #reactor-bulk_update-allow_stream_with } | `:keyset \| :offset \| :full_read` | `:keyset` | The 'worst' strategy allowed to be used to fetch records if the :stream strategy is chosen. See the `Ash.stream!/2` docs for more. | | [`assume_casted?`](#reactor-bulk_update-assume_casted?){: #reactor-bulk_update-assume_casted? } | `boolean` | `false` | Whether or not to cast attributes and arguments as input. This is an optimization for cases where the input is already casted and/or not in need of casting | | [`atomic_update`](#reactor-bulk_update-atomic_update){: #reactor-bulk_update-atomic_update } | `map` | | A map of atomic updates to apply. See `Ash.Changeset.atomic_update/3` for more. | | [`authorize_changeset_with`](#reactor-bulk_update-authorize_changeset_with){: #reactor-bulk_update-authorize_changeset_with } | `:filter \| :error` | `:filter` | If set to `:error`, instead of filtering unauthorized changes, unauthorized changes will raise an appropriate forbidden error | | [`authorize_query_with`](#reactor-bulk_update-authorize_query_with){: #reactor-bulk_update-authorize_query_with } | `:filter \| :error` | `:filter` | If set to `:error`, instead of filtering unauthorized query results, unauthorized query results will raise an appropriate forbidden error | | [`authorize_query?`](#reactor-bulk_update-authorize_query?){: #reactor-bulk_update-authorize_query? } | `boolean` | `true` | If a query is given, determines whether or not authorization is run on that query. | | [`batch_size`](#reactor-bulk_update-batch_size){: #reactor-bulk_update-batch_size } | `nil \| pos_integer` | | The number of records to include in each batch. Defaults to the `default_limit` or `max_page_size` of the action, or 100. | | [`filter`](#reactor-bulk_update-filter){: #reactor-bulk_update-filter } | `map \| keyword` | | A filter to apply to records. This is also applied to a stream of inputs. | | [`load`](#reactor-bulk_update-load){: #reactor-bulk_update-load } | `atom \| list(atom)` | `[]` | A load statement to apply to records. Ignored if `return_records?` is not true. | | [`lock`](#reactor-bulk_update-lock){: #reactor-bulk_update-lock } | `any` | | A lock statement to add onto the query. | | [`max_concurrency`](#reactor-bulk_update-max_concurrency){: #reactor-bulk_update-max_concurrency } | `non_neg_integer` | `0` | If set to a value greater than 0, up to that many tasks will be started to run batches asynchronously. | | [`notification_metadata`](#reactor-bulk_update-notification_metadata){: #reactor-bulk_update-notification_metadata } | `map \| Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | `%{}` | Metadata to be merged into the metadata field for all notifications sent from this operation. | | [`notify?`](#reactor-bulk_update-notify?){: #reactor-bulk_update-notify? } | `boolean` | `false` | Whether or not to generate any notifications. This may be intensive for large bulk actions. | | [`page`](#reactor-bulk_update-page){: #reactor-bulk_update-page } | `keyword` | `[]` | Pagination options, see [the pagination docs for more](read-actions.md#pagination). | | [`read_action`](#reactor-bulk_update-read_action){: #reactor-bulk_update-read_action } | `atom` | | The action to use when building the read query. | | [`return_errors?`](#reactor-bulk_update-return_errors?){: #reactor-bulk_update-return_errors? } | `boolean` | `false` | Whether or not to return all of the errors that occur. Defaults to false to account for large inserts. | | [`return_records?`](#reactor-bulk_update-return_records?){: #reactor-bulk_update-return_records? } | `boolean` | `false` | Whether or not to return all of the records that were inserted. Defaults to false to account for large inserts. | | [`return_stream?`](#reactor-bulk_update-return_stream?){: #reactor-bulk_update-return_stream? } | `boolean` | `false` | If set to `true`, instead of an `Ash.BulkResult`, a mixed stream is returned. | | [`reuse_values?`](#reactor-bulk_update-reuse_values?){: #reactor-bulk_update-reuse_values? } | `boolean` | `false` | Whether calculations are allowed to reuse values that have already been loaded, or must refetch them from the data layer. | | [`rollback_on_error?`](#reactor-bulk_update-rollback_on_error?){: #reactor-bulk_update-rollback_on_error? } | `boolean` | `true` | Whether or not to rollback the transaction on error, if the resource is in a transaction. | | [`select`](#reactor-bulk_update-select){: #reactor-bulk_update-select } | `atom \| list(atom)` | | A select statement to apply to records. Ignored if `return_records?` is not `true`. | | [`skip_unknown_inputs`](#reactor-bulk_update-skip_unknown_inputs){: #reactor-bulk_update-skip_unknown_inputs } | `atom \| String.t \| list(atom \| String.t)` | | A list of inputs that, if provided, will be ignored if they are not recognized by the action. Use `:*` to indicate all unknown keys. | | [`sorted?`](#reactor-bulk_update-sorted?){: #reactor-bulk_update-sorted? } | `boolean` | `false` | Whether or not to sort results by their input position, in cases where `return_records?` is set to `true`. | | [`stop_on_error?`](#reactor-bulk_update-stop_on_error?){: #reactor-bulk_update-stop_on_error? } | `boolean` | `false` | If `true`, the first encountered error will stop the action and be returned. Otherwise, errors will be skipped. | | [`strategy`](#reactor-bulk_update-strategy){: #reactor-bulk_update-strategy } | `list(:atomic \| :atomic_batches \| :stream)` | `[:atomic]` | The strategy or strategies to enable. `:stream` is used in all cases if the data layer does not support atomics. | | [`stream_batch_size`](#reactor-bulk_update-stream_batch_size){: #reactor-bulk_update-stream_batch_size } | `pos_integer` | | Batch size to use if provided a query and the query must be streamed. | | [`stream_with`](#reactor-bulk_update-stream_with){: #reactor-bulk_update-stream_with } | `:keyset \| :offset \| :full_read` | | The specific strategy to use to fetch records. See `Ash.stream!/2` docs for more. | | [`success_state`](#reactor-bulk_update-success_state){: #reactor-bulk_update-success_state } | `:success \| :partial_success` | `:success` | Bulk results can be entirely or partially successful. Chooses the `Ash.BulkResult` state to consider the step a success. | | [`timeout`](#reactor-bulk_update-timeout){: #reactor-bulk_update-timeout } | `timeout` | | If none is provided, the timeout configured on the domain is used (which defaults to `30_000`). | | [`transaction`](#reactor-bulk_update-transaction){: #reactor-bulk_update-transaction } | `:all \| :batch \| false` | `:batch` | Whether or not to wrap the entire execution in a transaction, each batch, or not at all. | | [`domain`](#reactor-bulk_update-domain){: #reactor-bulk_update-domain } | `module` | | The Domain to use when calling the action. Defaults to the Domain set on the resource or in the `ash` section. | | [`async?`](#reactor-bulk_update-async?){: #reactor-bulk_update-async? } | `boolean` | `true` | When set to true the step will be executed asynchronously via Reactor's `TaskSupervisor`. | | [`authorize?`](#reactor-bulk_update-authorize?){: #reactor-bulk_update-authorize? } | `boolean \| nil` | | Explicitly enable or disable authorization for the action. | | [`description`](#reactor-bulk_update-description){: #reactor-bulk_update-description } | `String.t` | | A description for the step | | [`undo_action`](#reactor-bulk_update-undo_action){: #reactor-bulk_update-undo_action } | `atom` | | The name of the action to call on the resource when the step is to be undone. | | [`undo`](#reactor-bulk_update-undo){: #reactor-bulk_update-undo } | `:always \| :never \| :outside_transaction` | `:never` | How to handle undoing this action | ## reactor.bulk_update.actor ```elixir actor source ``` Specifies the action actor ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`source`](#reactor-bulk_update-actor-source){: #reactor-bulk_update-actor-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the actor. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`transform`](#reactor-bulk_update-actor-transform){: #reactor-bulk_update-actor-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the actor before it is passed to the action. | ### Introspection Target: `Ash.Reactor.Dsl.Actor` ## reactor.bulk_update.inputs ```elixir inputs template ``` Specify the inputs for an action ### Examples ``` inputs %{ author: result(:get_user), title: input(:title), body: input(:body) } ``` ``` inputs(author: result(:get_user)) ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`template`](#reactor-bulk_update-inputs-template){: #reactor-bulk_update-inputs-template .spark-required} | `%{optional(atom) => Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value} \| keyword(Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value)` | | | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`transform`](#reactor-bulk_update-inputs-transform){: #reactor-bulk_update-inputs-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which will transform the inputs before executing the action. | ### Introspection Target: `Ash.Reactor.Dsl.Inputs` ## reactor.bulk_update.tenant ```elixir tenant source ``` Specifies the action tenant ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`source`](#reactor-bulk_update-tenant-source){: #reactor-bulk_update-tenant-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the tenant. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`transform`](#reactor-bulk_update-tenant-transform){: #reactor-bulk_update-tenant-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the tenant before it is passed to the action. | ### Introspection Target: `Ash.Reactor.Dsl.Tenant` ## reactor.bulk_update.wait_for ```elixir wait_for names ``` Wait for the named step to complete before allowing this one to start. Desugars to `argument :_, result(step_to_wait_for)` ### Examples ``` wait_for :create_user ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`names`](#reactor-bulk_update-wait_for-names){: #reactor-bulk_update-wait_for-names .spark-required} | `atom \| list(atom)` | | The name of the step to wait for. | ### Introspection Target: `Reactor.Dsl.WaitFor` ### Introspection Target: `Ash.Reactor.Dsl.BulkUpdate` ## reactor.change ```elixir change name, change ``` Declares a step that will modify a changeset. ### Nested DSLs * [argument](#reactor-change-argument) * [wait_for](#reactor-change-wait_for) ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`name`](#reactor-change-name){: #reactor-change-name .spark-required} | `atom` | | A unique name for this step. | | [`change`](#reactor-change-change){: #reactor-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 | |------|------|---------|------| | [`initial`](#reactor-change-initial){: #reactor-change-initial .spark-required} | `module \| Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | The initial value to work from, either a resource or a changeset | | [`description`](#reactor-change-description){: #reactor-change-description } | `String.t \| nil` | | An optional description for the change | | [`only_when_valid?`](#reactor-change-only_when_valid?){: #reactor-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. | | [`where`](#reactor-change-where){: #reactor-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. | | [`fail_if_invalid?`](#reactor-change-fail_if_invalid?){: #reactor-change-fail_if_invalid? } | `boolean` | `false` | Fail if the result of the change is an invalid changeset | ## reactor.change.argument ```elixir argument name, source \\ nil ``` Specifies an argument to a Reactor step. Each argument is a value which is either the result of another step, or an input value. Individual arguments can be transformed with an arbitrary function before being passed to any steps. ### Examples ``` argument :name, input(:name) ``` ``` argument :year, input(:date, [:year]) ``` ``` argument :user, result(:create_user) ``` ``` argument :user_id, result(:create_user) do transform & &1.id end ``` ``` argument :user_id, result(:create_user, [:id]) ``` ``` argument :three, value(3) ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`name`](#reactor-change-argument-name){: #reactor-change-argument-name .spark-required} | `atom` | | The name of the argument which will be used as the key in the `arguments` map passed to the implementation. | | [`source`](#reactor-change-argument-source){: #reactor-change-argument-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the argument. See `Reactor.Dsl.Argument` for more information. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`transform`](#reactor-change-argument-transform){: #reactor-change-argument-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the argument before it is passed to the step. | ### Introspection Target: `Reactor.Dsl.Argument` ## reactor.change.wait_for ```elixir wait_for names ``` Wait for the named step to complete before allowing this one to start. Desugars to `argument :_, result(step_to_wait_for)` ### Examples ``` wait_for :create_user ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`names`](#reactor-change-wait_for-names){: #reactor-change-wait_for-names .spark-required} | `atom \| list(atom)` | | The name of the step to wait for. | ### Introspection Target: `Reactor.Dsl.WaitFor` ### Introspection Target: `Ash.Reactor.Dsl.Change` ## reactor.create ```elixir create name, resource, action \\ nil ``` Declares a step that will call a create action on a resource. > #### Undo behaviour {: .tip} > > This step has three different modes of undo. > > * `never` - The result of the action is never undone. This is the default. > * `always` - The `undo_action` will always be called. > * `outside_transaction` - The `undo_action` will not be called when running inside a `transaction` block, but will be otherwise. ### Nested DSLs * [actor](#reactor-create-actor) * [inputs](#reactor-create-inputs) * [tenant](#reactor-create-tenant) * [wait_for](#reactor-create-wait_for) ### Examples ``` create :create_post, MyApp.Post, :create do inputs %{ title: input(:post_title), author_id: result(:get_user, [:id]) } actor result(:get_user) tenant result(:get_organisation, [:id]) end ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`name`](#reactor-create-name){: #reactor-create-name .spark-required} | `atom` | | A unique name for the step. | | [`resource`](#reactor-create-resource){: #reactor-create-resource .spark-required} | `module` | | The resource to call the action on. | | [`action`](#reactor-create-action){: #reactor-create-action } | `atom` | | The name of the action to call on the resource. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`initial`](#reactor-create-initial){: #reactor-create-initial } | `nil \| module \| Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | The initial value passed into the action. | | [`upsert_identity`](#reactor-create-upsert_identity){: #reactor-create-upsert_identity } | `atom` | | The identity to use for the upsert | | [`upsert?`](#reactor-create-upsert?){: #reactor-create-upsert? } | `boolean` | `false` | Whether or not this action should be executed as an upsert. | | [`domain`](#reactor-create-domain){: #reactor-create-domain } | `module` | | The Domain to use when calling the action. Defaults to the Domain set on the resource or in the `ash` section. | | [`async?`](#reactor-create-async?){: #reactor-create-async? } | `boolean` | `true` | When set to true the step will be executed asynchronously via Reactor's `TaskSupervisor`. | | [`authorize?`](#reactor-create-authorize?){: #reactor-create-authorize? } | `boolean \| nil` | | Explicitly enable or disable authorization for the action. | | [`description`](#reactor-create-description){: #reactor-create-description } | `String.t` | | A description for the step | | [`undo_action`](#reactor-create-undo_action){: #reactor-create-undo_action } | `atom` | | The name of the action to call on the resource when the step is to be undone. | | [`undo`](#reactor-create-undo){: #reactor-create-undo } | `:always \| :never \| :outside_transaction` | `:never` | How to handle undoing this action | ## reactor.create.actor ```elixir actor source ``` Specifies the action actor ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`source`](#reactor-create-actor-source){: #reactor-create-actor-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the actor. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`transform`](#reactor-create-actor-transform){: #reactor-create-actor-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the actor before it is passed to the action. | ### Introspection Target: `Ash.Reactor.Dsl.Actor` ## reactor.create.inputs ```elixir inputs template ``` Specify the inputs for an action ### Examples ``` inputs %{ author: result(:get_user), title: input(:title), body: input(:body) } ``` ``` inputs(author: result(:get_user)) ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`template`](#reactor-create-inputs-template){: #reactor-create-inputs-template .spark-required} | `%{optional(atom) => Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value} \| keyword(Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value)` | | | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`transform`](#reactor-create-inputs-transform){: #reactor-create-inputs-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which will transform the inputs before executing the action. | ### Introspection Target: `Ash.Reactor.Dsl.Inputs` ## reactor.create.tenant ```elixir tenant source ``` Specifies the action tenant ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`source`](#reactor-create-tenant-source){: #reactor-create-tenant-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the tenant. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`transform`](#reactor-create-tenant-transform){: #reactor-create-tenant-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the tenant before it is passed to the action. | ### Introspection Target: `Ash.Reactor.Dsl.Tenant` ## reactor.create.wait_for ```elixir wait_for names ``` Wait for the named step to complete before allowing this one to start. Desugars to `argument :_, result(step_to_wait_for)` ### Examples ``` wait_for :create_user ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`names`](#reactor-create-wait_for-names){: #reactor-create-wait_for-names .spark-required} | `atom \| list(atom)` | | The name of the step to wait for. | ### Introspection Target: `Reactor.Dsl.WaitFor` ### Introspection Target: `Ash.Reactor.Dsl.Create` ## reactor.destroy ```elixir destroy name, resource, action \\ nil ``` Declares a step that will call a destroy action on a resource. > #### Undo behaviour {: .tip} > > This step has three different modes of undo. > > * `never` - The result of the action is never undone. This is the default. > * `always` - The `undo_action` will always be called. > * `outside_transaction` - The `undo_action` will not be called when running inside a `transaction` block, but will be otherwise. ### Nested DSLs * [actor](#reactor-destroy-actor) * [inputs](#reactor-destroy-inputs) * [tenant](#reactor-destroy-tenant) * [wait_for](#reactor-destroy-wait_for) ### Examples ``` destroy :delete_post, MyApp.Post, :destroy do initial input(:post) actor result(:get_user) tenant result(:get_organisation, [:id]) end ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`name`](#reactor-destroy-name){: #reactor-destroy-name .spark-required} | `atom` | | A unique name for the step. | | [`resource`](#reactor-destroy-resource){: #reactor-destroy-resource .spark-required} | `module` | | The resource to call the action on. | | [`action`](#reactor-destroy-action){: #reactor-destroy-action } | `atom` | | The name of the action to call on the resource. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`initial`](#reactor-destroy-initial){: #reactor-destroy-initial .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | The record to update. | | [`return_destroyed?`](#reactor-destroy-return_destroyed?){: #reactor-destroy-return_destroyed? } | `boolean` | `false` | Whether or not the step should return the destroyed record upon completion. | | [`domain`](#reactor-destroy-domain){: #reactor-destroy-domain } | `module` | | The Domain to use when calling the action. Defaults to the Domain set on the resource or in the `ash` section. | | [`async?`](#reactor-destroy-async?){: #reactor-destroy-async? } | `boolean` | `true` | When set to true the step will be executed asynchronously via Reactor's `TaskSupervisor`. | | [`authorize?`](#reactor-destroy-authorize?){: #reactor-destroy-authorize? } | `boolean \| nil` | | Explicitly enable or disable authorization for the action. | | [`description`](#reactor-destroy-description){: #reactor-destroy-description } | `String.t` | | A description for the step | | [`undo_action`](#reactor-destroy-undo_action){: #reactor-destroy-undo_action } | `atom` | | The name of the action to call on the resource when the step is to be undone. | | [`undo`](#reactor-destroy-undo){: #reactor-destroy-undo } | `:always \| :never \| :outside_transaction` | `:never` | How to handle undoing this action | ## reactor.destroy.actor ```elixir actor source ``` Specifies the action actor ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`source`](#reactor-destroy-actor-source){: #reactor-destroy-actor-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the actor. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`transform`](#reactor-destroy-actor-transform){: #reactor-destroy-actor-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the actor before it is passed to the action. | ### Introspection Target: `Ash.Reactor.Dsl.Actor` ## reactor.destroy.inputs ```elixir inputs template ``` Specify the inputs for an action ### Examples ``` inputs %{ author: result(:get_user), title: input(:title), body: input(:body) } ``` ``` inputs(author: result(:get_user)) ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`template`](#reactor-destroy-inputs-template){: #reactor-destroy-inputs-template .spark-required} | `%{optional(atom) => Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value} \| keyword(Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value)` | | | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`transform`](#reactor-destroy-inputs-transform){: #reactor-destroy-inputs-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which will transform the inputs before executing the action. | ### Introspection Target: `Ash.Reactor.Dsl.Inputs` ## reactor.destroy.tenant ```elixir tenant source ``` Specifies the action tenant ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`source`](#reactor-destroy-tenant-source){: #reactor-destroy-tenant-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the tenant. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`transform`](#reactor-destroy-tenant-transform){: #reactor-destroy-tenant-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the tenant before it is passed to the action. | ### Introspection Target: `Ash.Reactor.Dsl.Tenant` ## reactor.destroy.wait_for ```elixir wait_for names ``` Wait for the named step to complete before allowing this one to start. Desugars to `argument :_, result(step_to_wait_for)` ### Examples ``` wait_for :create_user ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`names`](#reactor-destroy-wait_for-names){: #reactor-destroy-wait_for-names .spark-required} | `atom \| list(atom)` | | The name of the step to wait for. | ### Introspection Target: `Reactor.Dsl.WaitFor` ### Introspection Target: `Ash.Reactor.Dsl.Destroy` ## reactor.read_one ```elixir read_one name, resource, action \\ nil ``` Declares a step that will call a read action on a resource returning a single record. ### Nested DSLs * [actor](#reactor-read_one-actor) * [inputs](#reactor-read_one-inputs) * [tenant](#reactor-read_one-tenant) * [wait_for](#reactor-read_one-wait_for) ### Examples ``` read_one :post_by_id, MyApp.Post, :read do inputs %{id: input(:post_id)} end ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`name`](#reactor-read_one-name){: #reactor-read_one-name .spark-required} | `atom` | | A unique name for the step. | | [`resource`](#reactor-read_one-resource){: #reactor-read_one-resource .spark-required} | `module` | | The resource to call the action on. | | [`action`](#reactor-read_one-action){: #reactor-read_one-action } | `atom` | | The name of the action to call on the resource. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`fail_on_not_found?`](#reactor-read_one-fail_on_not_found?){: #reactor-read_one-fail_on_not_found? } | `boolean` | `false` | When set to true the step will fail if the resource is not found. | | [`domain`](#reactor-read_one-domain){: #reactor-read_one-domain } | `module` | | The Domain to use when calling the action. Defaults to the Domain set on the resource or in the `ash` section. | | [`async?`](#reactor-read_one-async?){: #reactor-read_one-async? } | `boolean` | `true` | When set to true the step will be executed asynchronously via Reactor's `TaskSupervisor`. | | [`authorize?`](#reactor-read_one-authorize?){: #reactor-read_one-authorize? } | `boolean \| nil` | | Explicitly enable or disable authorization for the action. | | [`description`](#reactor-read_one-description){: #reactor-read_one-description } | `String.t` | | A description for the step | ## reactor.read_one.actor ```elixir actor source ``` Specifies the action actor ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`source`](#reactor-read_one-actor-source){: #reactor-read_one-actor-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the actor. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`transform`](#reactor-read_one-actor-transform){: #reactor-read_one-actor-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the actor before it is passed to the action. | ### Introspection Target: `Ash.Reactor.Dsl.Actor` ## reactor.read_one.inputs ```elixir inputs template ``` Specify the inputs for an action ### Examples ``` inputs %{ author: result(:get_user), title: input(:title), body: input(:body) } ``` ``` inputs(author: result(:get_user)) ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`template`](#reactor-read_one-inputs-template){: #reactor-read_one-inputs-template .spark-required} | `%{optional(atom) => Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value} \| keyword(Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value)` | | | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`transform`](#reactor-read_one-inputs-transform){: #reactor-read_one-inputs-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which will transform the inputs before executing the action. | ### Introspection Target: `Ash.Reactor.Dsl.Inputs` ## reactor.read_one.tenant ```elixir tenant source ``` Specifies the action tenant ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`source`](#reactor-read_one-tenant-source){: #reactor-read_one-tenant-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the tenant. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`transform`](#reactor-read_one-tenant-transform){: #reactor-read_one-tenant-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the tenant before it is passed to the action. | ### Introspection Target: `Ash.Reactor.Dsl.Tenant` ## reactor.read_one.wait_for ```elixir wait_for names ``` Wait for the named step to complete before allowing this one to start. Desugars to `argument :_, result(step_to_wait_for)` ### Examples ``` wait_for :create_user ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`names`](#reactor-read_one-wait_for-names){: #reactor-read_one-wait_for-names .spark-required} | `atom \| list(atom)` | | The name of the step to wait for. | ### Introspection Target: `Reactor.Dsl.WaitFor` ### Introspection Target: `Ash.Reactor.Dsl.ReadOne` ## reactor.read ```elixir read name, resource, action \\ nil ``` Declares a step that will call a read action on a resource. ### Nested DSLs * [actor](#reactor-read-actor) * [inputs](#reactor-read-inputs) * [tenant](#reactor-read-tenant) * [wait_for](#reactor-read-wait_for) ### Examples ``` read :read_posts, MyApp.Post, :read ``` ``` read :read_posts_in_range, MyApp.Post, :read_in_range do inputs %{min_date: input(:min_date), max_date: input(:max_date)} end ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`name`](#reactor-read-name){: #reactor-read-name .spark-required} | `atom` | | A unique name for the step. | | [`resource`](#reactor-read-resource){: #reactor-read-resource .spark-required} | `module` | | The resource to call the action on. | | [`action`](#reactor-read-action){: #reactor-read-action } | `atom` | | The name of the action to call on the resource. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`domain`](#reactor-read-domain){: #reactor-read-domain } | `module` | | The Domain to use when calling the action. Defaults to the Domain set on the resource or in the `ash` section. | | [`async?`](#reactor-read-async?){: #reactor-read-async? } | `boolean` | `true` | When set to true the step will be executed asynchronously via Reactor's `TaskSupervisor`. | | [`authorize?`](#reactor-read-authorize?){: #reactor-read-authorize? } | `boolean \| nil` | | Explicitly enable or disable authorization for the action. | | [`description`](#reactor-read-description){: #reactor-read-description } | `String.t` | | A description for the step | ## reactor.read.actor ```elixir actor source ``` Specifies the action actor ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`source`](#reactor-read-actor-source){: #reactor-read-actor-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the actor. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`transform`](#reactor-read-actor-transform){: #reactor-read-actor-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the actor before it is passed to the action. | ### Introspection Target: `Ash.Reactor.Dsl.Actor` ## reactor.read.inputs ```elixir inputs template ``` Specify the inputs for an action ### Examples ``` inputs %{ author: result(:get_user), title: input(:title), body: input(:body) } ``` ``` inputs(author: result(:get_user)) ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`template`](#reactor-read-inputs-template){: #reactor-read-inputs-template .spark-required} | `%{optional(atom) => Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value} \| keyword(Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value)` | | | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`transform`](#reactor-read-inputs-transform){: #reactor-read-inputs-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which will transform the inputs before executing the action. | ### Introspection Target: `Ash.Reactor.Dsl.Inputs` ## reactor.read.tenant ```elixir tenant source ``` Specifies the action tenant ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`source`](#reactor-read-tenant-source){: #reactor-read-tenant-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the tenant. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`transform`](#reactor-read-tenant-transform){: #reactor-read-tenant-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the tenant before it is passed to the action. | ### Introspection Target: `Ash.Reactor.Dsl.Tenant` ## reactor.read.wait_for ```elixir wait_for names ``` Wait for the named step to complete before allowing this one to start. Desugars to `argument :_, result(step_to_wait_for)` ### Examples ``` wait_for :create_user ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`names`](#reactor-read-wait_for-names){: #reactor-read-wait_for-names .spark-required} | `atom \| list(atom)` | | The name of the step to wait for. | ### Introspection Target: `Reactor.Dsl.WaitFor` ### Introspection Target: `Ash.Reactor.Dsl.Read` ## reactor.transaction ```elixir transaction name, resources ``` Creates a group of steps which will be executed inside a data layer transaction. ### Nested DSLs * [wait_for](#reactor-transaction-wait_for) ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`name`](#reactor-transaction-name){: #reactor-transaction-name .spark-required} | `atom` | | A unique name for the step. | | [`resources`](#reactor-transaction-resources){: #reactor-transaction-resources .spark-required} | `module \| list(module)` | | A resource or list of resources to consider in the transaction. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`return`](#reactor-transaction-return){: #reactor-transaction-return } | `atom` | | The name of the step whose result will be returned as the return value of the transaction. | | [`timeout`](#reactor-transaction-timeout){: #reactor-transaction-timeout } | `pos_integer \| :infinity` | `15000` | How long to allow the transaction to run before timing out. | ## reactor.transaction.wait_for ```elixir wait_for names ``` Wait for the named step to complete before allowing this one to start. Desugars to `argument :_, result(step_to_wait_for)` ### Examples ``` wait_for :create_user ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`names`](#reactor-transaction-wait_for-names){: #reactor-transaction-wait_for-names .spark-required} | `atom \| list(atom)` | | The name of the step to wait for. | ### Introspection Target: `Reactor.Dsl.WaitFor` ### Introspection Target: `Ash.Reactor.Dsl.Transaction` ## reactor.update ```elixir update name, resource, action \\ nil ``` Declares a step that will call an update action on a resource. > #### Undo behaviour {: .tip} > > This step has three different modes of undo. > > * `never` - The result of the action is never undone. This is the default. > * `always` - The `undo_action` will always be called. > * `outside_transaction` - The `undo_action` will not be called when running inside a `transaction` block, but will be otherwise. ### Nested DSLs * [actor](#reactor-update-actor) * [inputs](#reactor-update-inputs) * [tenant](#reactor-update-tenant) * [wait_for](#reactor-update-wait_for) ### Examples ``` update :publish_post, MyApp.Post, :update do initial input(:post) inputs %{ published: value(true) } actor result(:get_user) tenant result(:get_organisation, [:id]) end ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`name`](#reactor-update-name){: #reactor-update-name .spark-required} | `atom` | | A unique name for the step. | | [`resource`](#reactor-update-resource){: #reactor-update-resource .spark-required} | `module` | | The resource to call the action on. | | [`action`](#reactor-update-action){: #reactor-update-action } | `atom` | | The name of the action to call on the resource. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`initial`](#reactor-update-initial){: #reactor-update-initial .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | The record to update. | | [`domain`](#reactor-update-domain){: #reactor-update-domain } | `module` | | The Domain to use when calling the action. Defaults to the Domain set on the resource or in the `ash` section. | | [`async?`](#reactor-update-async?){: #reactor-update-async? } | `boolean` | `true` | When set to true the step will be executed asynchronously via Reactor's `TaskSupervisor`. | | [`authorize?`](#reactor-update-authorize?){: #reactor-update-authorize? } | `boolean \| nil` | | Explicitly enable or disable authorization for the action. | | [`description`](#reactor-update-description){: #reactor-update-description } | `String.t` | | A description for the step | | [`undo_action`](#reactor-update-undo_action){: #reactor-update-undo_action } | `atom` | | The name of the action to call on the resource when the step is to be undone. | | [`undo`](#reactor-update-undo){: #reactor-update-undo } | `:always \| :never \| :outside_transaction` | `:never` | How to handle undoing this action | ## reactor.update.actor ```elixir actor source ``` Specifies the action actor ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`source`](#reactor-update-actor-source){: #reactor-update-actor-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the actor. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`transform`](#reactor-update-actor-transform){: #reactor-update-actor-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the actor before it is passed to the action. | ### Introspection Target: `Ash.Reactor.Dsl.Actor` ## reactor.update.inputs ```elixir inputs template ``` Specify the inputs for an action ### Examples ``` inputs %{ author: result(:get_user), title: input(:title), body: input(:body) } ``` ``` inputs(author: result(:get_user)) ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`template`](#reactor-update-inputs-template){: #reactor-update-inputs-template .spark-required} | `%{optional(atom) => Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value} \| keyword(Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value)` | | | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`transform`](#reactor-update-inputs-transform){: #reactor-update-inputs-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which will transform the inputs before executing the action. | ### Introspection Target: `Ash.Reactor.Dsl.Inputs` ## reactor.update.tenant ```elixir tenant source ``` Specifies the action tenant ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`source`](#reactor-update-tenant-source){: #reactor-update-tenant-source .spark-required} | `Reactor.Template.Element \| Reactor.Template.Input \| Reactor.Template.Result \| Reactor.Template.Value` | | What to use as the source of the tenant. | ### Options | Name | Type | Default | Docs | |------|------|---------|------| | [`transform`](#reactor-update-tenant-transform){: #reactor-update-tenant-transform } | `(any -> any) \| module \| nil` | | An optional transformation function which can be used to modify the tenant before it is passed to the action. | ### Introspection Target: `Ash.Reactor.Dsl.Tenant` ## reactor.update.wait_for ```elixir wait_for names ``` Wait for the named step to complete before allowing this one to start. Desugars to `argument :_, result(step_to_wait_for)` ### Examples ``` wait_for :create_user ``` ### Arguments | Name | Type | Default | Docs | |------|------|---------|------| | [`names`](#reactor-update-wait_for-names){: #reactor-update-wait_for-names .spark-required} | `atom \| list(atom)` | | The name of the step to wait for. | ### Introspection Target: `Reactor.Dsl.WaitFor` ### Introspection Target: `Ash.Reactor.Dsl.Update`