0

I am trying to create dynamic database connection for each of my models so I can pass a connection name using $model->setConnection('connection_name)

I've tried loads of answers to similar questions but nothing works

I have created a class which creates a new database connection and adds it the database config

<?php

namespace App;

use Illuminate\Support\Facades\Config;

class Clientdb
{
    public $connection;

    public function __construct($dbUser, $dbPassword, $dbName)
    {
        Config::set('database.connections.' . $dbUser, array(
            'driver'    => 'mysql',
            'host'      => '55.55.55.55',
            'port'      => '3306',
            'database'  => $dbName,
            'username'  => $dbUser,
            'password'  => $dbPassword,
            'unix_socket' => '',
            'charset'   => 'utf8',
            'collation' => 'utf8_general_ci',
            'prefix'    => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                \PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ));

        $this->connection = $dbUser;
    }

    public function connection() {
        return $this->connection;
    }
}

In my controller I create a new instance of my new class to add to the database config, then I create a new instance of my model and I pass the connection name to my model setConnection() function.

$this->clientdb = new Clientdb($dbUser, $dbPassword, $dbName);

$model = new \App\MyModel();
// dd($this->clientdb->connection);
$model->setConnection($this->clientdb->connection);
// dd($model);

$result = $model::where('id', $id)->first();

The problem is it still tries to use the connection that is set in the model and the connection is not updated. If I hard code the new connection name in my model it works but I need to make the connections dynamic as I don't want to keep adding to the database config manually.

What an I missing to update the connection in the model.

This is an example of my model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class MyModel extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'my_table';

    /**
     * Indicates if the model should be timestamped.
     *
     * @var bool
     */
    public $timestamps = false;

    /**
     * The connection name for the model.
     *
     * @var string
     */
    protected $connection = 'mysql';
}

sdfsf

AdRock
  • 2,959
  • 10
  • 66
  • 106

2 Answers2

0

It doesn't work because $model::where() is equivalent to (new MyModel)->where().

Call where() as a non-static method:

$result = $model->where('id', $id)->first();
                ^^

You can also use Model::on():

$result = MyModel::on($this->clientdb->connection)->where('id', $id)->first();
Jonas Staudenmeir
  • 24,815
  • 6
  • 63
  • 109
0

For Dynamic database connection, you have to think of two things

  1. Is your database is static?

  2. how do you want to call the connection?

In my project, my database name was not static. The DB name gets changed by the client during login time. So that I am using middleware, and have some complex code.

But if you are using a static database, that means one will be ENV and another will be runtime. then you can easily do this in a few steps.

  1. Mention database name on Database.php config

    Make a new connection array, like this way:

    HOST can be changed if your are going to a different host. Else you can get form ENV

    'bio_db' => [
        'driver' => 'mysql',
        'host' => 'YOURHOST',
        'port' => env('DB_PORT', '3306'),
        'database' => 'YourDatabaseName',
        'username' => 'DBUSERNAME',
        'password' => 'DBPASSWORD',
        'unix_socket' => env('DB_SOCKET', ''),
        'charset' => 'utf8mb4',
        'collation' => 'utf8mb4_unicode_ci',
        'prefix' => '',
        'prefix_indexes' => true,
        'strict' => false,
        'engine' => "InnoDB",
    ],
    
  2. Make the model like this:

    class BioDevices extends Model
    {
        protected $connection="bio_db";
    
        protected $table="devices";
    
        protected $guarded = [];
    
        public $timestamps = false;
    
        protected $primaryKey="DeviceId";
    }
    
  3. Call that table from the controller:

    public function test()
    {
        $data =BioDevices::get();
    
        return $data;
    }
    

If you have followed all steps, you will get the desired output like this:

 [
   {
    DeviceId: 1,
    DeviceFName: "BABU ------ COLLEGE",
    DeviceSName: "1912003",
    DeviceDirection: "altinout",
    SerialNumber: "BKU719XXX5",
    ConnectionType: "TCP/IP",
    IpAddress: "",
    BaudRate: null,
    CommKey: "0",
          .......
     },
    .......
 ]
Laurenz Albe
  • 209,280
  • 17
  • 206
  • 263
pankaj
  • 1
  • 17
  • 36