`:shared` context | automatically passing context to child actions
As part of the upcoming
Here is the relevant docs:
There are two kinds of contexts in Ash:
1. the context given to a changeset/action call, stored in
2. the context given to a callback function like
the above context in it's
and/or commonly needed keys for callbacks (actor, tenant, etc.).
Actions accept a free-form map of context, which can be used for whatever you like. Whenever context is set, it is deep merged. I.e if you do
There are two special keys to note:
The
The
is set, it is also written to the outer context. For example
This will generally happen automatically if you use one of the two abstractions provided by Ash for threading options through to nested action calls.
####
####
Ash.Scope capabilities, I decided to tackle something we've wanted for quite some time, which is the ability for some context to automatically be passed down to child actions & actions called from hooks. This will soon be in main.Here is the relevant docs:
Context
There are two kinds of contexts in Ash:
1. the context given to a changeset/action call, stored in
changeset.context,2. the context given to a callback function like
c:Ash.Resource.Change.change/3, which containsthe above context in it's
source_context key, as well as additional information specific to the callback,and/or commonly needed keys for callbacks (actor, tenant, etc.).
Actions accept a free-form map of context, which can be used for whatever you like. Whenever context is set, it is deep merged. I.e if you do
changeset |> Ash.Changeset.set_context(%{a: %{b: 1}}) |> Ash.Changeset.set_context(%{a: %{c: 2}}), the resulting context will be %{a: %{b: 1, c: 2}}. Structs are not merged.There are two special keys to note:
:private
The
:private key is reserved for use by Ash itself. You shouldn't read from or write to it.:shared
The
:shared key will be passed to all nested actions built by Ash, and should be passed by you to any actions you call within changes/preparations etc. Whenever :shared contextis set, it is also written to the outer context. For example
set_context(%{shared: %{locale: "en"}}) is equivalent to set_context(%{shared: %{locale: "en"}, locale: "en"})This will generally happen automatically if you use one of the two abstractions provided by Ash for threading options through to nested action calls.
>Careful with shared {: .warning}
Shared context is passed to all nested actions, so don't pass massive values around, and also don't set context
####
Ash.ScopeAsh.Scope is newer and is the recommended way to do this. In action callbacks in Ash, you will be provided with a context, which can be passed down as a scope option when running nested actions or building nested changesets/queries. For example:####
Ash.Context.to_opts/2Ash.Context.to_opts/2 is a helper function that converts a context map into a list of options that can be passed to nested actions. It automatically passes the shared context to the nested action as well.