わかりました。最初の質問は何度も変更されたため、削除して質問を再定式化することにしました。問題の適切な解決策を見つけるために、さまざまなモデル名で小さなテストケースプロジェクトを作成しました。
警告:データベースとテーブルを混在させないでください
動機:法的な問題とパフォーマンスの問題のために、ユーザーデータを複数に分割しましたデータベース。
現在、私は複数のUser
を持つCakePHPプロジェクトに取り組んでおり、各User
には独自のデータベース複数のテーブル(cars
はテーブルの1つです)。今、私は最初に何かを説明する必要があります:
すべてのUser
には独自のデータベース(テーブルではなく、データベース)があるため、データベース名は次のようになります。
app
(これはアプリのメインデータベースです)users
permissions
(この質問には関係ありません)app_user1
(User.id
1はこの全体を所有していますデータベース)cars
(a table完全にUser.id
1が所有)app_user2
(User.id
2はこの全体を所有していますデータベース)cars
(a テーブル完全にUser.id
2が所有)データベース/テーブル-定義とそれらのモデルとの関係を明確にする可能性のある小さな図面を作成しました。
問題!!!
User
がログインするまで、どのdatabaseに接続するかわかりません。User
とそのdatabasesは動的に作成されるため、 app/Config/database.php
を使用できません。
そのため、私は現在、Model
クラスとConnectionManager
クラスに拡張機能を記述して、CakePHPの基本的なデータベースの動作をバイパスしています。したがって、Car
モデルは、使用するデータベースを認識しています。しかし、私はこれがもっと簡単にできると感じています!
だから私はそれがすべて1つの質問に要約されると思います:
これを行う簡単な方法はありますか?!
私の問題を読んで理解するために時間と労力を費やしてくれる人に感謝します!
この紳士 ( オリビエ )も同じ問題を抱えていました! (1年前) 彼は書いたController
sの小さな適応!それはかなり小さく、1.3と2.xで動作することがわかりました。
とにかく、これが私の最終的な解決策であり、app/Model/AppModel.php
に入れました。
class AppModel extends Model
{
/**
* Connects to specified database
*
* @param String name of different database to connect with.
* @param String name of existing datasource
* @return boolean true on success, false on failure
* @access public
*/
public function setDatabase($database, $datasource = 'default')
{
$nds = $datasource . '_' . $database;
$db = &ConnectionManager::getDataSource($datasource);
$db->setConfig(array(
'name' => $nds,
'database' => $database,
'persistent' => false
));
if ( $ds = ConnectionManager::create($nds, $db->config) ) {
$this->useDbConfig = $nds;
$this->cacheQueries = false;
return true;
}
return false;
}
}
そして、これが私のapp/Controller/CarsController.php
での使用方法です。
class CarsController extends AppController
{
public function index()
{
$this->Car->setDatabase('cake_sandbox_client3');
$cars = $this->Car->find('all');
$this->set('cars', $cars);
}
}
私は賭けています、私はこの問題の最初でも最後でもありません。ですから、この情報が人々とCakePHPコミュニティを見つけることを本当に望んでいます。
データベースの実際の名前をコードに書き留めるという考えは好きではありません。複数のデータベースの場合、必要な数のデータベースを設定できるdatabase.phpファイルがあります。
特定のモデルのデータベースをオンザフライで「切り替える」場合は、setDataSourceメソッド。 ( ここ を参照)
たとえば、2つのデータベースがある場合、例として、database.phpファイルでそれらを「default」と「sandbox」として定義できます。
次に、コードで:
$this->Car->setDataSource('sandbox');
サンドボックスは構成の名前であり、データベースの実際の名前はdatabase.phpファイルに1回だけ書き込まれます。
Mysqlの完全な表記法を使用して、いつでも任意のデータベースにクエリを実行できます。 F.ex。:
SELECT * FROM my_schema_name.table_name;
ケーキの方法:
$db = $this->getDataSource();
$query = array(
'fields' => array('*'),
'table' => 'my_schema_name.table_name'
);
$stmt = $db->buildStatement($query, $this);
$result = $db->execute($stmt);
Database.phpで
public $mongo = array(
'datasource' => 'Mongodb.MongodbSource',
'database' => 'database_name_mongo',
'Host' => 'localhost',
'port' => 27017,
);
あなたのコントローラーであなたは使うことができます
$this->Organisation->setDataSource('mongo');
次に、次のようなクエリを適用します
this->Organisation->find('all');
これは受け入れられた答えの人々です。これにより、新しいデータソースがすでに存在する場合にエラーを防ぐことができます。
public function setDatabase($database, $datasource = 'default')
{
$newDatasource = $datasource . '_' . $database;
try {
// return the new datasource if it's already existed
$db = ConnectionManager::getDataSource($newDatasource);
$this->useDbConfig = $newDatasource;
$this->cacheQueries = false;
return true;
} catch (Exception $e) {
// debug($e->getMessage());
}
$db = ConnectionManager::getDataSource($datasource);
$db->setConfig(array(
'name' => $newDatasource,
'database' => $database,
'persistent' => false
));
if ( $ds = ConnectionManager::create($newDatasource, $db->config) ) {
$this->useDbConfig = $newDatasource;
$this->cacheQueries = false;
return true;
}
return false;
}