Ecto Plugin | Uni

:ok, prefix end The uni_ecto_plugin often bundles a caching mechanism. Setting a tenant prefix usually involves a database lookup to validate the tenant exists. This adds latency.

# Bad user = Repo.get(User, 1) |> Repo.preload(:orders) user = Repo.get(User, 1) orders = Repo.preload(user, :orders, prefix: UniEcto.Plugin.get_tenant_prefix()) 3. Mix Tasks Crashing Error: Running mix phx.server fails because no tenant is set during compilation. Fix: Guard your plugin calls: uni ecto plugin

def get_orders_with_global_settings do query = from o in Order, join: s in Setting, on: true, # Global join select: o, s Repo.all(query, prefix: UniEcto.Plugin.get_tenant_prefix()) end Handling Migrations with The Plugin The trickiest part of multi-tenancy is database schema updates. You cannot just run mix ecto.migrate . :ok, prefix end The uni_ecto_plugin often bundles a

defmodule MyApp.Repo.Migrations.AddNotesToOrders do use Ecto.Migration import UniEcto.MigrationHelpers def up do # Runs on all existing tenants + public for tenant <- UniEcto.Plugin.all_tenants() do execute("SET search_path TO #tenant") alter table(:orders) do add :notes, :text end end end end # Bad user = Repo

mix uni_ecto.migrate --tenant all mix uni_ecto.migrate --tenant customer_456 In a true SaaS app, tenants are created on the fly via a signup form.

Unlike basic foreign key scoping ( WHERE tenant_id = ? ), the uni_ecto_plugin often supports (separate schemas or separate databases). It seamlessly switches between tenants at the connection level.