动态创建的数据源未传递到CakePHP中的关联模型

Chi*_*Sky 3 php cakephp cakephp-2.0

我有一个模型-汽车-汽车有几个相关模型,让我们考虑其中一个与hasMany关系相关的模型-车轮

在我的CarsController中,我使用以下代码动态生成数据源-

$schemaName = $this->Session->read('User.schema'); 
$config = ConnectionManager::getDataSource('default')->config;
$config['database'] = $schemaName;
ConnectionManager::create($schemaName, $config);
Run Code Online (Sandbox Code Playgroud)

然后,使用以下代码行在我的汽车模型中设置此数据源

$this->Car->setDataSource($schemaName);
Run Code Online (Sandbox Code Playgroud)

之后,我可以查询Car并在Car上进行操作,但是,如果我尝试使用以下语句在Wheel上进行操作-我会收到错误消息

$this->Car->Wheel->create();
$this->Car->Wheel->save($wheelData);
Run Code Online (Sandbox Code Playgroud)

我得到的错误是-错误:[MissingTableException]在数据源默认值中找不到模型Wheel的工作台。

由于某种原因,数据源没有从父模型传递到关联的子模型。如果我使用以下行在Wheel中显式设置数据源,则一切正常。

$this->Car->Wheel->setDataSource($schemaName);
Run Code Online (Sandbox Code Playgroud)

任何人都可以帮助阐明这种行为以及如何解决此问题吗?我觉得这很不方便,是因为我的父模型有几个关联的模型(还具有关联的模型),并且在每个模型上分别设置数据源听起来并不正确。

附带问题-是否可以在尝试动态创建数据源之前检查数据源是否已存在?我有一个用于包装整个代码的for循环,每次循环迭代最终都会创建一个新的数据源

我正在使用CakePHP 2.5.4

Mat*_*att 5

这是一些将setDatasource()调用传递给关联模型的代码,如果您只希望Car模型通过其数据源,请将此代码放入Car模型,如果您希望所有模型通过,请将其放入 AppModel.php

public function setDatasource($datasource = null) {
    foreach (array_keys($this->getAssociated()) as $modelName) {
        $this->{$modelName}->setDatasource($datasource);
    }
    parent::setDatasource($datasource);
}
Run Code Online (Sandbox Code Playgroud)

为了回答您的意见,我想补充public $dynamicDb = falseAppModel.php,意思是假将是这个变量的默认值,然后在模型中加入覆盖它public $dynamicDb = true,然后改变了上述函数:

public function setDatasource($datasource = null) {
    foreach (array_keys($this->getAssociated()) as $modelName) {
        if ($this->{$modelName}->dynamicDb === true) {
            $this->{$modelName}->setDatasource($datasource);
        }
    }
    parent::setDatasource($datasource);
}
Run Code Online (Sandbox Code Playgroud)

(由于我现在不在开发PC上,因此我尚未测试此修订功能,但这是一个相当简单的更改,应该可以使用)

要在创建数据源之前检查数据源是否存在,我可以看到两种可能的方法,一种是通过调用ConnectionManager::getDatasource($schemaName)并捕获异常(如果数据源不存在),或者调用ConnectionManager::sourceList()并检查您的数据源$schemaName是否在返回的数组中,这是一种实现第一种选择:

$schemaName = $this->Session->read('User.schema'); 
try {
    ConnectionManager::getDatasource($schemaName)
} catch (MissingDatasourceException $e) {
    $config = ConnectionManager::getDataSource('default')->config;
    $config['database'] = $schemaName;
    ConnectionManager::create($schemaName, $config);
}
Run Code Online (Sandbox Code Playgroud)

第二种选择:

$datasources = ConnectionManager::sourceList();
$schemaName = $this->Session->read('User.schema'); 
if (!in_array($schemaName, $datasources)) {
    $config = ConnectionManager::getDataSource('default')->config;
    $config['database'] = $schemaName;
    ConnectionManager::create($schemaName, $config);
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助