2

I have a multi-tenant app that has a master database with client info, this has settings for different databases. By reading the URL on startup I can figure out the tenant they are accessing, then switch the connection and cache the settings so that it is using the correct tenants database. This part works but the problem comes up with migrations.

The regular Laravel migrations only handle the master table, so I added a migration folder for "tenants" this needs to run on all tenants for each update. To do this I use the following class

<?php namespace App\Console\Commands\Tenants; use Illuminate\Console\Command; use Illuminate\Support\Facades\DB; class UpdateTenant extends Command { protected $signature = 'tenant:update {slug}'; protected $description = 'Update a tenants database'; protected $migrator; public function __construct() { parent::__construct(); $this->migrator = app()->make('migrator'); } public function fire() { $arguments = $this->arguments(); if ($account = DB::connection('root')->table('accounts')->where('slug', '=', $arguments['slug'])->first()) { config()->set('database.connections.tenant.database', $arguments['slug']); $this->migrator->setConnection('tenant'); if (! $this->migrator->repositoryExists()) { $this->call('migrate:install', ['--database' => 'tenant']); } $this->migrator->run([$this->laravel->basePath() . '/' . 'database/tenants']); foreach ($this->migrator->getNotes() as $note) { $this->output->writeln($note); } } } } 

As you can see this is just for one tenant defined by the slug, I have another command to loop and call the artisan command on all tenants.

foreach ($accounts as $account) { $this->call('tenant:update', ['slug' => $account->slug]); } 

The issue here is that although checking the value of the slug it is correctly finding the correct tenant info, the connection gets stuck on the first tenant despite switching the connection. Even if I try to switch it to the root and back it just ignores the change to the config. Is there anyway to tell laravel to reset the connection so that it will use the updated values in the config to reconnect?

3
  • Try using DB::disconnect('tenant'); after you set the config and before your migrator->setConnection() call. Commented Jun 15, 2017 at 5:04
  • 1
    Seems to be working with that! thank you, if you want to write an answer I will accept it, if not I can put one together. Commented Jun 15, 2017 at 16:34
  • I can write one up, glad it worked for you! Commented Jun 15, 2017 at 16:35

1 Answer 1

2

Disconnect from the current connection in between tenants with:

config()->set('database.connections.tenant.database', $arguments['slug']); DB::disconnect('tenant');<----- add this $this->migrator->setConnection('tenant'); 

This will clean up the resource connection and force the app to re-establish itself with the correct configuration settings.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.