Хорошо, мой первый вопрос был изменен так много раз, что я решил удалить его и переформулировать мой вопрос. Я разработал небольшой тестовый проект с разными именами моделей, чтобы найти подходящее решение для моей проблемы.
Предупреждение : не смешивайте базы данных со столами
Мотивация . Я разделил пользовательские данные на несколько баз данных для юридических и рабочих проблем.
В настоящее время я работаю над проектом CakePHP, который имеет несколько User
, и каждый User
имеет собственную базу данных с несколькими таблицами ( cars
– одна из таблиц ). Теперь мне нужно сначала что-то объяснить:
Каждый User
имеет свою собственную базу данных (а не таблицу, базу данных ), поэтому имена базы данных выглядят следующим образом.
app
(это основная база данных приложения)
users
app_user1
( User.id
1 владеет всей этой базой данных )
cars
( таблица полностью принадлежит User.id
1) app_user2
( User.id
2 владеет всей этой базой данных )
cars
( таблица полностью принадлежит User.id
2) Я сделал небольшой рисунок, который мог бы прояснить базу данных / таблицы- определения и их отношения к моделям:
Проблема!!!
Я не знаю, к какой базе данных подключиться, пока User
войдет в систему. User
и их базы данных создаются динамически, поэтому я не могу использовать app/Config/database.php
.
Поэтому в настоящее время я пишу расширение для классов Model
и ConnectionManager
чтобы обойти основные действия базы данных CakePHP. Таким образом, модель Car
знает, какую базу данных использовать. Но у меня просто ощущение, что это можно сделать легче!
Поэтому я думаю, все это сводится к одному вопросу:
Есть ли более простой способ сделать это ?!
Спасибо всем, кто будет тратить время и силы на чтение и понимание моей проблемы!
У этого господина ( Оливье ) была такая же проблема! (Год назад) Он написал небольшую адаптацию для Controller
! Он довольно маленький, и получается, он работает в 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 . (см. здесь )
Например, если у вас есть две базы данных, вы можете определить их в файле database.php как «default» и «sandbox» в качестве примера.
Затем в вашем коде:
$this->Car->setDataSource('sandbox');
Песочница – это имя конфигурации, и фактическое имя базы данных записывается только один раз в файле database.php.
Вы всегда можете запрашивать любые базы данных, используя полную нотацию в 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);
В вашей базе данных.php
public $mongo = array( 'datasource' => 'Mongodb.MongodbSource', 'database' => 'database_name_mongo', 'host' => 'localhost', 'port' => 27017, );
В вашем контроллере вы можете использовать
$this->Organisation->setDataSource('mongo');
затем примените запрос типа
this->Organisation->find('all');