kamaroly

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

zachdaniel

Creator of Ash

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

zachdaniel

Creator of Ash

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.

Where Next?

Popular in Questions Top

mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

Other popular topics Top

AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 54120 245
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement