DatabaseTenancyBootstrapper
The DatabaseTenancyBootstrapper handles connecting to the tenant database when tenancy is initialized.
This bootstrapper is used with multi-database tenancy.
It works by:
- Creating a new connection named
tenant - Changing the default database connection to
tenant
This means any new database queries, that do not have an explicit connection specified, will execute on the tenant database — without any other code changes in your application.
It also means you can still interact with your central connection by referencing it explicitly, rather
than having Laravel use the default connection. On models, you can use the CentralConnection trait for this.
Using explicit connections
Section titled “Using explicit connections”You can use these traits on your models to interact with the central or tenant domain explicitly:
Stancl\Tenancy\Database\Concerns\CentralConnection— always worksStancl\Tenancy\Database\Concerns\TenantConnection— only works in the tenant context
Here, “in the tenant context” means when tenancy is initialized, i.e. on requests with a tenant identification
middleware or after a manual tenancy()->initialize() (including in closures passed to $tenant->run()).
While using these model traits is absolutely not necessary, it can be a good practice if you value more strictness
in your code. If you accidentally try to use for instance App\Models\Tenant\User in the central context, you will
get an exception if the TenantConnection trait is used. You will not necessarily get an exception without that trait,
especially if you also have a central users table. This can be a dangerous mistake in some contexts, especially if, like
in this example, the table exists in both contexts but the models may significantly differ in behavior.
When using raw DB facade calls, you can use:
DB::connection('name_of_your_central_connection')for the central connection. To avoid having to pass this name statically, you can also useDB::connection(config('tenancy.database.central_connection')). It can be a good idea to name your central connectioncentral, however you should also keep in mind that some testing setups change the default connection (e.g. usingsqlitewith:memory:instead of your regularcentralconnection) and your app should still work with that.DB::connection('tenant')for the tenant connection.
Hardening the tenant connection
Section titled “Hardening the tenant connection”DatabaseTenancyBootstrapper::$harden is an opt-in check that runs on each tenancy initialization and verifies that the
tenant connection doesn’t point at the central database, or at another tenant’s database:
DatabaseTenancyBootstrapper::$harden = true;If either is the case, the connection is reverted back to central and a RuntimeException is thrown.
This is not a common issue, so the check is disabled by default. Think of it as an optional security feature for applications with extremely sensitive data, where you’d rather have requests fail than have any chance of queries running against the wrong database. Note that verifying this costs a few queries on each initialization, which can negate the performance benefits of cached tenant lookup.