我的问题与this question中描述的问题相同 - 这是我有一个中央数据库来托管用户登录信息,而每个用户都有自己的事务数据库,除了登录之外,它们还将用于其他操作。在登录完成之前无法知道用户将操作哪个数据库,因此无法使用数据库配置文件。
除了一个(主要)问题之外,提供此问题的解决方案完美无缺。它似乎没有帮助模型上的关系。换句话说,我能够在模型中设置与我的控制器直接关联的数据库名称,它工作正常,但我的模型有许多belongsTo
和hasMany
关系,动态设置的数据库名称不会传播这些相关的模型。
我正在使用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模式行为。有什么想法吗?