0

I want to combine two applications. One of these as module. There are two different databases. The Module use another database as the base appliaction.

I have created the db connection, which is a component in config.php

return [
    'class' => 'yii\db\Connection',
    'dsn' => 'mysql:host=localhost;dbname=test_db',
    'username' => 'root',
    'password' => '',    
    'charset' => 'utf8',
];

And I have created an ModuleActiveRecord Class which overwrites the Active Record function getDB():

class ModuleActiveRecord extends ActiveRecord
{
    public static function getDb()
    {
        $db = Yii::$app->controller->module->db;
        return Yii::createComponent($db);
}

I get the error message: The table does not exist. Anyone an idea??

Shorty
  • 55
  • 1
  • 7
  • 1
    you just need to add another database connection `component` lets say `db2` and then create a basemodel inside your `module/models` folder and override the `getDb()` method to return the database connection like `return Yii::$app->db2` and all other models should extend that model, i dont get why you are returning `return Yii::createComponent($db);` – Muhammad Omer Aslam Nov 27 '18 at 00:36
  • You should not use `Yii::$app->controller` in your model, it breaks MVC pattern. – rob006 Nov 27 '18 at 11:07

2 Answers2

1

Copy the db connection file and import both connections in config (web.php):

'components' => [
    ...
    'db' => require(__DIR__ . '/db.php'),
    'db_copy' => require(__DIR__ . '/db_copy.php'),
]

Then override the db connection in the ActiveRecord which uses the copy db like this:

public static function getDb()
{
    return Yii::$app->get('db_copy');
}
ttdijkstra
  • 618
  • 4
  • 14
1

You can add multiple database connections like the other answers, for example: db/db_for_module.

You can also configure the module like I do(Example using Yii2 advanced template):

// in common/config/main.php
[
    'db' => [
        'class' => 'yii\db\Connection',
        'dsn' => 'mysql:host=localhost;dbname=test_db',
        'username' => 'root',
        'password' => '123456',    
        'charset' => 'utf8',
    ],
    'modules' => [
        'v1' => [
            'class' => \frontend\modules\v1\Module::class,
            // Increase the component configuration of the module
            'components' => [
                'db' => [
                    'class' => 'yii\db\Connection',
                    'dsn' => 'mysql:host=localhost;dbname=test_db_for_module',
                    'username' => 'root',
                    'password' => '111111',    
                    'charset' => 'utf8',
                ],
            ],
        ],
    ],
]

Definition of v1 module

// in frontend/modules/Module.php
<?php

namespace frontend\modules\v1;

/**
 * v1 module definition class.
 */
class Module extends \yii\base\Module
{
    /**
     * {@inheritdoc}
     */
    public $controllerNamespace = 'frontend\modules\v1\controllers';
}

However, you have to call the db component in a special way in the module's code, for example:

// in frontend/modules/v1/controllers/TestController.php
<?php

namespace frontend\modules\v1\controllers;

/**
 * Test Controller
 */
class TestController extends \yii\web\Controller {

    public function actionTest()
    {
        \Yii::$app->modules['v1']->db->createCommand(...); // This db points to the db connection of this module configuration
        // or
        $this->module->db->createCommand(...) // This db points to the db connection of this module configuration
    }
}

The benefits of doing this:

  • You can use the same name: db (if this is what you expect, although it's called in a special way)
  • The code other than this module can't see the configuration about this db.
  • Even if you don't have a special db connection for this module, you can still call the default db connection correctly using the above method (maybe this is not what you expect)
  • Can clearly indicate that a special db connection configuration is used here

Note: This is just a way to override the application default components in the module for reference. I have not practiced this method, but I have tested this is feasible.

Luna
  • 2,132
  • 2
  • 7
  • 14
  • Thank you very much. This is exactly what I imagined. Unfortunately I get an error. **'Trying to get property of non-object'**. I have extended the module configuration with db data (in base application) and call the db component in the module Class (under function 'init'), right? – Shorty Nov 27 '18 at 11:12
  • This configuration does not need to modify any Yii framework code, which is originally supported. What changes have you caused? Give you the code of my Module class as a reference: class Module extends \yii\base\Module { /** * {@inheritdoc} */ public $controllerNamespace = 'frontend\modules\v1\controllers'; } – Luna Nov 27 '18 at 12:15
  • Great, I have found the mistake. Thank you!! – Shorty Nov 27 '18 at 13:54
  • Annotation: I have created the new db connection in the config file of the module. It works fine. – Shorty Nov 27 '18 at 14:09
  • I re-edited the example and hope this will give you and others some help. – Luna Nov 27 '18 at 14:21