How to set YII2 Multiple DB Configurable?

how to set database configurable in active record ?

This my file : app\models\multi_db\Devices;

<?php
namespace app\models\multi_db;

use yii\db\ActiveRecord;

class Devices extends ActiveRecord
{ 
     private static $dbConn;

     public function __construct($config=[])
     {
        switch ($config['server']) {
        case '2':
            self::$dbConn = \Yii::$app->dbtwo;
            break;
        case '3':
            self::$dbConn = \Yii::$app->dbthree;
            break;          
        default:
            self::$dbConn = \Yii::$app->dbone;
            break;
        }
     }

     public static function getDb()
     {
        return self::$dbConn;
     }

     public function findDevice($id)
     {
        return self::findOne($id);
     }
}

This my code to get device :

$model = new Devices(['server' => 3]);
$device = $model->findDevice(1);

But this generate error:

Undefined index: server

I think the constructor not set in findDevice method?

How can I fix this?

Upvotes: 2

Views: 169

Answers (2)

soju
soju

Reputation: 25312

Well, findOne() will use your constructor without providing server config, that's why you get this error, you could simply try :

public function __construct($config=[])
{
    if (isset($config['server'])) switch ($config['server']) {
        case '2':
            self::$dbConn = \Yii::$app->dbtwo;
            break;
        case '3':
            self::$dbConn = \Yii::$app->dbthree;
            break;          
        default:
            self::$dbConn = \Yii::$app->dbone;
            break;
    }
    // don't forget to call parent constructor
    parent::__construct($config);
}

But I think the logic here is wrong, this should be set using a static method, e.g :

class Devices extends ActiveRecord
{

    private static $dbConn;

    public static function setServer($id)
    {
        switch ($id) {
            case '2':
                self::$dbConn = \Yii::$app->dbtwo;
                break;
            case '3':
                self::$dbConn = \Yii::$app->dbthree;
                break;          
            default:
                self::$dbConn = \Yii::$app->dbone;
                break;
        }
    }

    public static function getDb()
    {
        if (self::$dbConn===null)
            self::$dbConn = \Yii::$app->dbone;

        return self::$dbConn;
    }

}

Then :

// find device on dbone
$device = Devices::findOne(1);

// find device on dbtwo
Devices::setServer(2);
$device = Devices::findOne(1);

Upvotes: 1

ScaisEdge
ScaisEdge

Reputation: 133360

Seems you have some mistake,

If you use findOne(id) mean you are getting to retrieve the value from DB. When you should create you server this way

$model = new Device();
$model->server = 3;
$model->save();

You have a mistake also in switch (you select always the same db ..dbtwo ) a think you should assign different db (dbOne, dbTwo, dbthree)

class Devices extends ActiveRecord
{ 
 private static $dbConn;

 public function __construct($config=[])
 {
    switch ($config['server']) {
    case '2':
        self::$dbConn = \Yii::$app->dbtwo;
        break;
    case '3':
        self::$dbConn = \Yii::$app->dbthree;
        break;          
    default:
        self::$dbConn = \Yii::$app->dbone;
        break;
    }
 }

 public static function getDb()
 {
    return self::$dbConn;
 }

 public function findDevice($id)
 {
    return self::findOne($id);
 }
}

Upvotes: 1

Related Questions