4

I have been building a web application that tracks statistics. These statistics can range between different companies.
I decided to use a main database to house all of the login credentials and each company gets a separate database to themselves.
After the user logins in they will be redirected to this function...

/**
* Redirects the user to the appropriate sub link
*/
public function redirect()
{
    Config::set('database.connections.club.database', Auth::user()->club->db_name);
    if (Auth::user()->person->role_id == 4) {
        return Redirect::to('employee/club_manager/home');
    }
}

This function sets the secondary database configuration called club's database equal to the user's associated club.

However when I try to access this configuration later on...

/**
* Handle an incoming request.
*
* @param  \Illuminate\Http\Request $request
* @param  \Closure $next
* @return mixed`enter code here`
*/
public function handle($request, Closure $next)
{
    dd(Config::get('database.connections.club.database'));
    if (Auth::user()->role->id == 4)
        return $next($request);
}

The dd() will return '', which is the default setting I set in the database.php file.

My question is, how can I save a configuration setting across requests as it appears that Config::set is only saving the setting for a single request.

Sérgio Reis
  • 2,483
  • 2
  • 19
  • 32
gofish
  • 347
  • 3
  • 10
  • Why don't you store these database details also in your main database along with user credentials? – lephleg Dec 03 '16 at 21:02
  • What do you mean? – gofish Dec 03 '16 at 22:50
  • You can create a new column in your `users` table on your main database, called 'database` where you can store the name of the database instance meant for that user/company. Let me know if need a separate answer. – lephleg Dec 03 '16 at 22:58
  • Could you put a separate answer? I'm really lost how that would solve this solution. (I am self taught everything and am quite new to SQL) – gofish Dec 03 '16 at 23:27
  • I've posted a new answer but I'm afraid it might be marked as off-topic relative to the title. You may have to create a new question if this happens. – lephleg Dec 04 '16 at 00:40
  • 1
    You can use one of packages which allow you to save data to config files at runtime. Here's one of these packages: https://github.com/daftspunk/laravel-config-writer – Alexey Mezenin Dec 03 '16 at 21:30

2 Answers2

1

Well, you can't actually use config for this.

Configuration values that are set at run-time are only set for the current request, and will not be carried over to subsequent requests.

Laravel documentation reference.

Workaround

As a hacky workaround, and if you are not willing to use your main database to store the company database connection data, you could use a custom configuration file that you could update on run-time.

This is very similar to how the original config file works and it should keep the data persistently. However you have to build a control mechanism around it to keep the entries unique and consistent:

Update Config on Runtime Persistently

You could also look for a package for this so you dont have to re-invent the wheel. Check laravel-config-writer (disclaimer: never personally used it).

lephleg
  • 1,724
  • 2
  • 21
  • 41
1

After OP's request, I submit a second answer as a different approach.

If this is only intented for database connection details, you could use the following approach with multiple database connections in a single Laravel application.

In app/config/database.php you define two different connections. One for your main database where your users table is stored and one dynamic for the per-client instance:

'default' => 'mysql_main',
'connections' => [

    'mysql_main' => [
        'driver' => 'mysql',
        'host' => env('DB_HOST', 'localhost'),
        'port' => env('DB_PORT', '3306'),
        'database' => env('DB_DATABASE', 'forge'),
        'username' => env('DB_USERNAME', 'forge'),
        'password' => env('DB_PASSWORD', ''),
        'charset' => 'utf8',
        'collation' => 'utf8_unicode_ci',
        'prefix' => '',
        'strict' => false,
        'engine' => null,
    ],

    'mysql_company' => [
        'driver' => 'mysql',
        'host' => env('DB_HOST', 'localhost'),
        'port' => env('DB_PORT', '3306'),
        'database' => Auth::user()->club->db_name,
        'username' => Auth::user()->club->db_user,
        'password' => Auth::user()->club->db_pass,
        'charset' => 'utf8',
        'collation' => 'utf8_unicode_ci',
        'prefix' => '',
        'strict' => false,
        'engine' => null,
    ],

],

As you can see you dont actually need to read the connection details of the second connection from the config file (it would still be used to get host, port and any common details with your main database), you can pass the different connection details dynamically from your logged-in user. However this will require you to have created all the databases for every user in advance.

After you have managed to connect to both databases, you will have to select the active connection anytime you execute a query.

Hopefully Schema Builder, Query Builder and Eloquent support this out of the box:

Shema Builder

Schema::connection('mysql_company')->create('statisticA', function($table)
{
    $table->increments('id'):
});

Query Builder

$companyStatA = DB::connection('mysql_company')->select(...);

Eloquent Model

class StatisticA extends Eloquent {

    protected $connection = 'mysql_company';

}

Controller

class SomeController extends BaseController {

    public function someMethod()
    {
        $statA = new StatisticA;

        $statA->setConnection('mysql_company');

        $something = $statA->find(1);

        return $something;
    }

}

However what would be tricky is to define relationships between models stored in different databases. It is be possible but it strongly depends on your database driver and settings.

I doubt it would function correctly between different types of databases (eg MySQL as your main database and PostgreSQL for you company databases), so I'd suggest you to stick with MySQL and see how this goes.

lephleg
  • 1,724
  • 2
  • 21
  • 41
  • This is what I am looking for, however when doing this I get the following error... Fatal error: Class 'Auth' not found in F:\trapstats_v5\config\database.php on line 73. – gofish Dec 04 '16 at 02:07