https://spatie.be/docs/laravel-multitenancy/v2/installation/base-installation
Instalamos el package a nuestro proyecto.
composer require "spatie/laravel-multitenancy:^2.0"
Publicamos la configuración
php artisan vendor:publish --provider="Spatie\Multitenancy\MultitenancyServiceProvider" --tag="multitenancy-config"
Editamos el archivo app/Http/Kernel.php
protected $middlewareGroups = [
'tenant.web' => [
\Spatie\Multitenancy\Http\Middleware\NeedsTenant::class,
\Spatie\Multitenancy\Http\Middleware\EnsureValidTenantSession::class,
],
'tenant.api' => [
\Spatie\Multitenancy\Http\Middleware\NeedsTenant::class,
]
];
Agregando configuración Enable
config/multitenancy.php
return [ /** * Enable / disable multitenant */ 'enabled' => true,
Usando el middleware
Editamos rutas en el archivo app/Providers/RouteServiceProvider.php
$this->routes(function () {
$api = ['api'];
$web = ['web'];
if (config('multitenancy.enabled')) {
array_push($api, 'tenant.api');
array_push($web, 'tenant.web');
}
Route::prefix('api')
->middleware($api)
->namespace($this->namespace)
->group(base_path('routes/api.php'));
Route::middleware($web)
->namespace($this->namespace)
->group(base_path('routes/web.php'));
});
'connections' => [
'tenant' => [
'driver' => 'mysql',
'database' => null,
// other options such as host, username, password, ...
],
'landlord' => [
'driver' => 'mysql',
'database' => 'name_of_landlord_db',
// other options such as host, username, password, ...
],
],
php artisan vendor:publish --provider="Spatie\Multitenancy\MultitenancyServiceProvider" --tag="multitenancy-migrations"
php artisan migrate --path=database/migrations/landlord --database=landlord
Archivo config/multitenancy.php
'switch_tenant_tasks' => [
Spatie\Multitenancy\Tasks\SwitchTenantDatabaseTask::class,
],
Las migraciones de tenants es en la carpeta habitual database/migrations
/* * The connection name to reach the tenant database. * * Set to `null` to use the default connection. */ 'tenant_database_connection_name' => 'tenant', /* * The connection name to reach the landlord database */ 'landlord_database_connection_name' => 'landlord',
php artisan tenants:artisan "migrate --database=tenant"
'tenant_finder' => Spatie\Multitenancy\TenantFinder\DomainTenantFinder::class,
config/multitenancy.php
'tenant_model' => \App\Models\CustomTenantModel::class,
App\Models\Tenant.php
class Tenant extends BaseTenant
{
protected $guarded = [];
public static function booted()
{
static::creating(fn (Tenant $tenant) => $tenant->createDatabase($tenant));
static::created(fn (Tenant $tenant) => $tenant->runMigrationsSeeders($tenant));
}
public function migration($tenant)
{
$this->createDatabase($tenant);
}
public function createDatabase($tenant)
{
$database_name = parse_url(config('app.url'), PHP_URL_HOST).'_'.Str::random(4);
$database = Str::of($database_name)->replace('.', '_')->lower()->__toString();
ray($database);
$query = "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?";
$db = DB::select($query, [$database]);
if (empty($db)) {
DB::connection('tenant')->statement("CREATE DATABASE {$database};");
$tenant->database = $database;
}
return $database;
}
public function runMigrationsSeeders($tenant)
{
$tenant->refresh();
Artisan::call('tenants:artisan', [
'artisanCommand' => 'migrate --database=tenant --seed --force',
'--tenant' => "{$tenant->id}",
]);
}
}