Multitenancy in AshPostgres is implemented via postgres schemas. For more information on schemas, see postgres' schema documentation
Implementing multitenancy via schema's involves tracking "tenant migrations" separately from migrations for your public schema. You can see what this looks like by simply creating a multitenant resource, and using the migration generator
mix ash_postgres.generate_migrations --apis My.Api. It will put schema specific migrations in
priv/repo/tenant_migrations. When you generate migrations, you'll want to be sure to audit migrations in both directories. Additionally, when you deploy, you'll want to run your migrations, as well as running them with the migrations path
The generated migrations include a lot of niceties around multitenancy. Specifically, foreign keys will point at tables in the correct schema, and foreign keys to non-multitenant resources will point to the correct table. If you are using attribute multitenancy, foreign keys to tables also using attribute multitenancy will be composite foreign keys, including the tenant attribute as well as the referencing field.
Migrations in the tenant directory will call
repo().all_tenants(), which is a callback you will need to implement in your repo that should return a list of all schemas that need to be migrated.
By setting the
template configuration, in the
manage_tenant section, you can cause the creation/updating of a given resource to create/rename tenants. For example:
defmodule MyApp.Organization do use Ash.Resource, ... postgres do ... manage_tenant do template ["org_", :id] end end end
With this configuration, if you create an organization, it will create a corresponding schema, e.g.
org_10 in the database. Then it will run your tenant migrations on that schema. To override the tenant_migrations path, implement the
manage_tenant is nested inside the
postgres block. This is because the method of managing tenants is specific to postgres, and if another data layer supported multitenancy they may or may not support managing tenants in the same way.