Skip to content

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.

You can use these traits on your models to interact with the central or tenant domain explicitly:

  1. Stancl\Tenancy\Database\Concerns\CentralConnection — always works
  2. Stancl\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:

  1. DB::connection('name_of_your_central_connection') for the central connection. To avoid having to pass this name statically, you can also use DB::connection(config('tenancy.database.central_connection')). It can be a good idea to name your central connection central, however you should also keep in mind that some testing setups change the default connection (e.g. using sqlite with :memory: instead of your regular central connection) and your app should still work with that.
  2. DB::connection('tenant') for 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:

app/Providers/TenancyServiceProvider.php
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.