CakePHP的多个数据库 - 将数据库名称从Controller设置为Model

时间:2014-12-26 10:06:39

标签: php cakephp cakephp-2.0

我的问题与this question中描述的问题相同 - 这是我有一个中央数据库来托管用户登录信息,而每个用户都有自己的事务数据库,除了登录之外,它们还将用于其他操作。在登录完成之前无法知道用户将操作哪个数据库,因此无法使用数据库配置文件。

除了一个(主要)问题之外,提供此问题的解决方案完美无缺。它似乎没有帮助模型上的关系。换句话说,我能够在模型中设置与我的控制器直接关联的数据库名称,它工作正常,但我的模型有许多belongsTohasMany关系,动态设置的数据库名称不会传播这些相关的模型。

我正在使用CakePHP 2.5.4

汽车控制器代码

public function beforeFilter() {
    parent::beforeFilter();
    $dbName = $this->Auth->User('schema'); //accessing database name from session
    $this->Car->setDatabase($dbName); //setting dynamic database name in Model
    $this->set('cars', $this->Car->find('all));
}

App Model方法

public function setDatabase($database) {
      $dbConfig  = ConnectionManager::getDataSource('default')->config;

      $dbConfig['database'] = $database;

      ConnectionManager::create($database, $dbConfig);
      $this->useDbConfig  = $database;
      $this->cacheQueries = false;
}

使用上面的代码,代码完美地查询动态设置数据库中的Car表,但不查询任何相关模型。所有这些都是空白的。

要解决,我必须在控制器代码中进行以下更改 -

public function beforeFilter() {
    parent::beforeFilter();
    $dbName = $this->Auth->User('schema'); //accessing database name from session
    $this->Car->setDatabase($dbName); //setting dynamic database name in Model
    $this->Car->Dealer->setDatabase($dbName); //setting dynamic database in related models
    $this->Car->Dealer->Location->setDatabase($dbName); 
    $this->set('cars', $this->Car->find('all));
}

虽然这种方法有效 - 但我觉得有一种更清洁的方法可以解决这个问题。欢迎任何建议/想法。

我一直在努力的另一种方法是在我的所有模型中设置一个名为dynamicDB的变量。如果将其设置为TRUE,则模型将使用不同的数据库。我在AppModel中使用以下代码测试了这种方法

public function __construct($id = false, $table = null, $ds = null) { 
    if ($this->dynamicDB) { 
        // Get saved company/database name 
        $this->dbName = 'otherDB'; 
        // Get common user-specific config (default settings in database.php) 
        $config = ConnectionManager::getDataSource('default')->config; 

        // Set correct database name 
        $config['database'] = $this->dbName; 
        // Add new config to registry 
        ConnectionManager::create($this->dbName, $config); 
        // Point model to new config 
        $this->useDbConfig = $this->dbName; 
    }

    parent::__construct($id, $table, $ds); 
}

这很完美,也很理想 - 但我不知道如何在控制器的AppModel中设置动态数据库名称。正如您所看到的,我在上面的代码中硬编码数据库名称只是为了测试它。我能想到的唯一解决方案是让AppModel直接访问我的会话变量,但这会违反MVC模式行为。有什么想法吗?

0 个答案:

没有答案