kamaroly
How to Auto-Set Tenant in Ash Multitenancy Based on Actor in Resource Queries
I am working on a multi-tenant Ash project. Each user always has a current_tenant. I am finding myself having to pass actor: user and tenant: user.current_tenant.domain on each query.
Since the current_tenant is directly accessible via user A.K.A actor, is there a way to automatically set the tenant in the resource definition based on the actor so that instead of having to pass tenant like the following:
Contacts.get_contact(contact_id, actor: user, tenant: user.current_tenant.domain)
I will just pass the actor like the following and the tenant resolution will automatically happen based on the actor?
Contacts.get_contact(contact_id, actor: user)
Marked As Solved
zachdaniel
Hm…it’s an interesting question. We could potentially add another protocol called Ash.TenantFromActor or something like that to handle that, but it’s a bit complex to do that automatically. There are resources that could have a tenant or not have a tenant, so we can’t assume providing an actor is also providing a tenant. You could try this on your resources:
preparations do
prepare MyApp.Preparations.SetTenant
end
changes do
prepare MyApp.Changes.SetTenant
end
and the definitions
defmodule MyApp.Preparations.SetTenant do
use Ash.Resource.Preparation
def prepare(query, _, context) do
if context.actor do
Ash.Query.set_tenant(query, context.actor.current_tenant.domain)
else
query
end
end
end
defmodule MyApp.Changes.SetTenant do
use Ash.Resource.Change
def change(changeset, _, context) do
if context.actor do
Ash.Changeset.set_tenant(changeset, context.actor.current_tenant.domain)
else
changeset
end
end
def atomic(changeset, opts, context), do: {:ok, change(changeset, opts, context)}
end
Also Liked
zachdaniel
There must be a case where we are not passing the actor to an underlying actor that we call. Please open an issue in ash_double_entry.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









