Notes from Ollie Read's article Laravel multi-tenancy, avoiding over engineering.
https://ollieread.com/articles/laravel-multi-tenancy-avoiding-over-engineering
App\Services\TenantManager
This gets/sets the current tennant. loadTenant()
method houses the query to find the tenant.
In the AppServiceProvider, binds an instance of the TenantManager
class to the Container.
Binds the Tenant
model to the Container to use the TenantManager::getTenant()
method.
IdentifyTentant
middleware. Uses the TenantManager
to recognise the tenant.
All tenant routes are wrapped in this middleware.
It gets the subdomain/domain/path to recognise the tenant.
Laravel can remove this tenant parameter from the Request object so it's not passed to Controllers.
$request->route()->forgetParameter('tenant');
Middleware uses the TenantManager::loadTenant().
route()
method on the Tenant
model.
return app('url')->route($name, array_merge([$this->slug], $parameters), $absolute);
Use a scope, App\Scopes\TenantOwnedScope
. Applies the scope to the query Builder.
Also withoutTenancy()
method, e.g. for admin areas.
Use a trait App\Concerns\OwnedByTenant
to add this scope to models.
Trait uses a bootOwnedByTenant
method to add the scope and sets the relation with static::creating()
.
And a BelongsTo tenant()
method.
Copy the Unique and Exists rules from Illuminate\Validation\Rule
and copy them to the TenantManager()
, adding a conditional for the tenant.