How can I bypass or re-evaluate multi-tenancy for specific aggregates?

I have an aggregate for Count, but the problem is that it conflicts with the structure of the application when it comes to multi-tenancy. The relevant code looks like this: JsonAPI
aggregates do
count :media_count, :media do
public? true
read_action :read_any
description "Returns total number of media files in this category"
end
end
aggregates do
count :media_count, :media do
public? true
read_action :read_any
description "Returns total number of media files in this category"
end
end
As you can see, I’ve even changed the read_action to :read_any, and that action itself bypasses multi-tenancy:
read :read_any do
description "Reads media bypassing tenant filtering"
multitenancy :bypass
pagination offset?: true, default_limit: 20, max_page_size: 100, countable: true
end
read :read_any do
description "Reads media bypassing tenant filtering"
multitenancy :bypass
pagination offset?: true, default_limit: 20, max_page_size: 100, countable: true
end
However, I’m still running into issues. One workaround I tried was using Ash.load! and explicitly setting the tenant, like so:
Ash.load!(category, [:media_count],
tenant: media_query_tenant,
authorize?: false
)
Ash.load!(category, [:media_count],
tenant: media_query_tenant,
authorize?: false
)
But that didn’t solve the problem either. When I don’t include the aggregate in the JSON response, everything works fine. But as soon as I include it, I get the following warning:
[warning] `0cf5973a-b075-40f7-bdc5-72dc13af5742`: AshJsonApi.Error not implemented for error:

** (Ash.Error.Invalid.TenantRequired) Bread Crumbs:
> Error returned from: MishkaCms.Runtime.MediaCategory.read

Queries against the MishkaCms.Runtime.MediaCategory resource require a tenant to be specified
[warning] `0cf5973a-b075-40f7-bdc5-72dc13af5742`: AshJsonApi.Error not implemented for error:

** (Ash.Error.Invalid.TenantRequired) Bread Crumbs:
> Error returned from: MishkaCms.Runtime.MediaCategory.read

Queries against the MishkaCms.Runtime.MediaCategory resource require a tenant to be specified
It seems like it’s still using the default read action internally, instead of the custom :read_any. I can create calculate for it but how can fix my problem here in aggregates Thank you in advance
Solution:
I don't believe that we have an option to bypass multitenancy for aggregates or calculations that use aggregates. You'll need to open an issue.
Jump to solution
4 Replies
Shahryar
ShahryarOP2mo ago
I even created a custom one
aggregates do
custom :media_count, :media, :integer do
public? true
implementation MishkaCms.Runtime.Aggregates.MediaCountAggregate
description "Returns total number of media files in this category using custom aggregate that bypasses multitenancy"
end
end
aggregates do
custom :media_count, :media, :integer do
public? true
implementation MishkaCms.Runtime.Aggregates.MediaCountAggregate
description "Returns total number of media files in this category using custom aggregate that bypasses multitenancy"
end
end
still it dose not let me
defmodule MishkaCms.Runtime.Aggregates.MediaCountAggregate do
@moduledoc """
Custom aggregate for counting media items that handles multitenancy properly.
This aggregate bypasses tenant requirements by using a direct query.
"""
use AshPostgres.CustomAggregate
require Ecto.Query

@impl true
def dynamic(_opts, binding) do
# Count media items directly related to this category
# This uses the database to count efficiently without tenant context
Ecto.Query.dynamic(
[],
fragment(
"(SELECT COUNT(*) FROM media m WHERE m.media_category_id = ? AND m.archived_at IS NULL)",
field(as(^binding), :id)
)
)
end
end
defmodule MishkaCms.Runtime.Aggregates.MediaCountAggregate do
@moduledoc """
Custom aggregate for counting media items that handles multitenancy properly.
This aggregate bypasses tenant requirements by using a direct query.
"""
use AshPostgres.CustomAggregate
require Ecto.Query

@impl true
def dynamic(_opts, binding) do
# Count media items directly related to this category
# This uses the database to count efficiently without tenant context
Ecto.Query.dynamic(
[],
fragment(
"(SELECT COUNT(*) FROM media m WHERE m.media_category_id = ? AND m.archived_at IS NULL)",
field(as(^binding), :id)
)
)
end
end
And i think it is about AshJsonAPI
Solution
ZachDaniel
ZachDaniel2mo ago
I don't believe that we have an option to bypass multitenancy for aggregates or calculations that use aggregates. You'll need to open an issue.
Shahryar
ShahryarOP2mo ago
Sorry Dear Zach, it is for Ash or AshJson? to open issue
ZachDaniel
ZachDaniel2mo ago
Ash core

Did you find this page helpful?