Home 15 de Abril, 2021 Laravel Multitenancy

Laravel Multitenancy

Documentación

https://spatie.be/docs/laravel-multitenancy/v2/installation/base-installation


Instalación

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"


Middleware

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,


Routes

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'));
    });


Configuración de Bases de Datos


'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, ...
    ],
],


Migraciones de Landlord


php artisan vendor:publish --provider="Spatie\Multitenancy\MultitenancyServiceProvider" --tag="multitenancy-migrations"


php artisan migrate --path=database/migrations/landlord --database=landlord


Switch entre bases de datos Automatico

Archivo config/multitenancy.php

'switch_tenant_tasks' => [
    Spatie\Multitenancy\Tasks\SwitchTenantDatabaseTask::class,
],


Creando base de datos de Tenant y Migraciones

Las migraciones de tenants es en la carpeta habitual database/migrations


Configuración de Conexiones

/*
     * 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"


Determinando el tenand actual

'tenant_finder' => Spatie\Multitenancy\TenantFinder\DomainTenantFinder::class,


Tenant Personalizado

config/multitenancy.php

'tenant_model' => \App\Models\CustomTenantModel::class,


Tenant

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}",
    ]);
  }
}



Sin Comentarios Aún. Se el primero!