动态创建的数据源未传递到CakePHP中的关联模型 [英] Dynamically created datasource not being passed to associated models in CakePHP

查看:123
本文介绍了动态创建的数据源未传递到CakePHP中的关联模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a Model - Car - the Car has several associated models, lets consider one of them which is linked with the hasMany relationship - Wheel

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

In my CarsController, I dynamically generate a datasource using the following code -

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

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

Then I set this datasource in my Car Model using the following line of code

$this->Car->setDataSource($schemaName);

之后,我可以查询和操作汽车,但是,如果我试图操作车轮使用以下语句 - 我收到错误

After this I am able to query and operate on Car, however, if I try to operate on Wheel using the following statements - I get an error

$this->Car->Wheel->create();
$this->Car->Wheel->save($wheelData);

我得到的错误是 -
错误:[MissingTableException]在数据源默认中找不到。

The error I get is - Error: [MissingTableException] Table wheels for model Wheel was not found in datasource default.

由于某种原因,数据源未从父模型传递到关联的子模型。如果我显式设置数据源在Wheel使用下面的行,那么一切都很好。

For some reason the datasource is not being passed from Parent model to associated child models. If I explicitly set the datasource in Wheel using the following line then everything works fine.

$this->Car->Wheel->setDataSource($schemaName);

任何人都可以帮助阐明这种行为以及如何解决这个问题?我发现这个不方便的原因是,我的父模型有几个相关的模型(进一步有相关联的模型)和设置数据源单独对每个他们不正确。

Can anyone help shed some light on this behavior and how to fix this? The reason I find this inconvenient is that my parent model has several associated models (which further have associated models) and setting datasource individually on each of them doesnt sound right.

问题 - 有没有办法检查数据源是否已经存在,然后尝试动态创建一个?我有一个for循环包装这整个代码,每个循环迭代将最终创建一个新的数据源

Side Question - is there a way to check if a datasource already exists before trying to create one dynamically? I have a for-loop that wraps this entire code and each loop iteration will end up creating a new datasource

我使用CakePHP 2.5.4

I am using CakePHP 2.5.4

推荐答案

这里是一些代码,将通过setDatasource()调用相关联的模型,如果你只想要Car模型通过它的数据源放这个代码在Car模型中,如果你想让所有模型通过,将它放在 AppModel.php

Here is some code which will pass the setDatasource() call to associated models, if you want only the Car model to pass through its datasource put this code in the Car model, if you want all models to pass through, put it in AppModel.php

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

要回答您的意见,我将添加 public $在 AppModel.php 中,表示false将是此变量的默认值,因此在您的模型中通过添加<$ c来覆盖它的dynamicDb = false $ c> public $ dynamicDb = true ,然后将上述函数更改为:

To answer your comment, I would add public $dynamicDb = false in AppModel.php, meaning false would be the default value for this variable, then in your models override it by adding public $dynamicDb = true, then change the above function to:

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

(我没有测试过这个修改的函数,因为我不在我的dev电脑现在,但它是一个相当简单的改变,它应该工作)

(I haven't tested this amended function as I'm not on my dev PC right now, but its a fairly simple change and it should work)

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

To check if a datasource already exists before you create one, I can see two possible methods, one is by calling ConnectionManager::getDatasource($schemaName) and catching the exception if the datasource does not exist, or call ConnectionManager::sourceList() and check if your $schemaName is in the returned array, here's an implementation of the first option:

$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);
}

,第二个选项:

$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);
}

希望这有助于

这篇关于动态创建的数据源未传递到CakePHP中的关联模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆