steele232
Hey All!
I’m really new to Ash but I think it’s got a lot of potential to save me a ton of time so I’m working through this for a proof-of-concept / MVP I’m creating.
TL;DR is I’m trying to create an app and a multi-tenant database using schema-isolated multi-tenants approach (one schema per organization) - I’ve got it creating tables but I don’t see any schemas being created, so I just have one accounts table and I should be seeing multiple schemas (one per org) with an accounts table in each schema.
Prior to trying to add in multi-tenancy, I was creating the tables “like normal” and was able to work through the relationship creating and attributes creation. I got that all set up in postgres.
When I started switching the resources to be multi-tenant, I noticed that the multi-tenant migrations started being created during codegen (i.e. mix ash.codegen add_multitenancy_to_remaining ) which seemed good and promising, but that’s where I got stuck because I noticed no multiple schemas were getting created. Also, I tried creating an entry in the organizations table to see if that would trigger a new schema. It didn’t. Then I ran mix ecto.migrate again after the new organizations record was added to the database, but no new schemas were added to the database.
and when I do mix ecto.drop, mix ecto.create and mix ecto.migrate --migrations-path priv/repo/tenant_migrations
then I get all the same issues where I only have one accounts table and not multiple schemas - though I’m NOT seeing an organizations table (my only non-multi-tenant resource right now).
When I do normal mix ecto.drop, mix ecto.create and mix ecto.migrate , then I get the organizations table but still not multiple schemas.
Do I need to redo all my migration code with the codegen from scratch? Do you think something got messed up along the way because the resources started out as being non-multi-tenant? Or am I looking at the issue all wrong? if so, please enlighten me
So here’s the code for inspection :
I marked all of them as multi-tenant like this (full code)
defmodule MyApp.MyDomain.Account do
use Ash.Resource,
domain: MyApp.MyDomain,
data_layer: AshPostgres.DataLayer
postgres do
table "accounts"
repo MyApp.Repo
end
multitenancy do
strategy :context
end
actions do
defaults [:read]
create :signup do
accept [:username, :email]
end
end
attributes do
uuid_primary_key :id
attribute :username, :string do
allow_nil? false
public? true
end
attribute :email, :string do
allow_nil? true
public? true
end
end
end
and I created an Organization resource which I believe is set to be non-multi-tenant because there should just be one table of tenants (full code)
defmodule MyApp.MyDomain.Organization do
use Ash.Resource,
domain: MyApp.MyDomain,
data_layer: AshPostgres.DataLayer
postgres do
table "organizations"
repo MyApp.Repo
end
actions do
defaults [:read]
create :create do
accept [:name]
end
end
attributes do
uuid_primary_key :id
attribute :name, :string do
allow_nil? false
public? true
end
end
postgres do
manage_tenant do
template ["org_", :id]
end
end
defimpl Ash.ToTenant do
def to_tenant(%{id: id}, resource) do
if Ash.Resource.Info.data_layer(resource) == AshPostgres.DataLayer
&& Ash.Resource.Info.multitenancy_strategy(resource) == :context do
"org_#{id}"
else
id
end
end
end
end
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #ai
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 7- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
zachdaniel
Try using
mix ash.migrate && mix ash.migrate —tenantsinstead ofmix ecto.migratesteele232
Oh cool - I did not know those existed
I ran those and I got a new error
And I was able to make the needed change and I updated my repo module to have this method
And from there I was able to do ash.migrate --tenants with NO organizations in the db (still no schemas)
and then I added a new organization and did ash.migrate --tenants and I got a new error:
I found that updating the code to replace the dashes with underscores in the org id helped remove the error.
So that’s good.
So now I’m able to run ash.migrate with absolutely no errors but I still see no additional schemas in my DB
List of db schemas
Any additional wisdom? Should I re-create the migrations?
Am I missing something?
steele232
Also I’m open to doing things differently. I just know my app will be multi-tenant and so I was hoping for a nice way to handle that with Ash. I read in the docs that :attribute strategy can work but it made it sound like it moght not be ideal and so schema separation appealed to me.
zachdaniel
Right, so new schemas aren’t created for existing organizations when you run
migrate --tenants. New schemas are created when organizations are created. Additionally, you will need to do something to adjust the templated schema inmanage_template.My suggestion is to add a global change that happens on creates that sets the schema name. You can use the
idfor that if you like, as you are now, and do the replacement in the change.Then, set the template like so:
And then use that
schema_namewhen listing tenants in the repo.Then, new schemas should be created whenever you create an organization.
steele232
Ah perfect thank you!
I was using SQL CLI inserts before to add organizations but once I started using the ash elixir code to add the organizations, then the magic worked like you said and I got the new schema and tables being created.
I did get the ID and schema name stuff working with more of your advice above so thank you. I’ll post the code below
Last question: Should I be seeing tables for my multi-tenant resources in my
publicschema? I see theorganizationstable there in addition to all the other tables; I was only expecting to see the organizations table there because all my other resources are tenant-specific resources. Are tenant-specific tables supposed to be created in the plublic schema? And if so, why?I have confirmed that the
organizationstable is not present in the tenant-specific schemas.zachdaniel
Unless you have
global? trueconfigured, then no you should only see your tenant resources in each schema, not the public schema. Then with your current setup only organizations should be in the public schema.Did you reset your database? Could it be something from an earlier time you set things up?
steele232
Hey, good news:
After re-generating the migrations, everything works as expected. So that’s good!
Thanks again for the help from before!