Je suis toute nouvelle dans la communauté et je cherche une solution à mon problème !
J’ai une dizaine de bases de données (une par magasin) qui sont utilisées par le même site. J’ai, dans chacune d’entre elles une table avec la même structure (produit). Est-il possible de créé un modèle qui utiliserais les différentes tables de chaque base ?
Je ne suis pas certain d’avoir complètement compris le problème, mais ce que je peux te dire :
tu peux configurer plusieurs connexions de bases de données dans le fichier de configuration de Yii :
return array(
...
'components' => array(
'db' => array( // Connexion par défaut
'connectionString' => 'mysql:host=dbhost;dbname=mydb1',
...
),
'db2' => array( // Deuxième connexion
'connectionString' => 'mysql:host=dbhost;dbname=mydb2',
'username' => '********',
'password' => '********',
...
'class' => 'CDbConnection' // A rajouter pour que Yii comprenne que c'est une autre connexion
),
avec Giix, tu peux sélectionner quelle connexion de base de données est utilisée pour générer tes modèles. Cependant (je m’avance peut-être), Giix ne devrait pas pouvoir te permettre de réaliser un modèle “multi-base”. C’est à toi de le modifier manuellement de manière à permettre cela.
J’ai bien compris le problème ou je suis hors-sujet ?
J’ai trouvé une autre solution, dis moi ce que tu en penses !
J’ai généré un model d’une base d’un des magasin que j’ai modifié :
abstract class BaseProduct extends GxActiveRecord
{
var $store = NULL;
public function __construct($store)
{
$this->store = $store;
Yii::app()->user->setState('orderDatabase', $this->store);
$model = new BOorders();
$model->getDbConnection();
}
public static function model($className=__CLASS__)
{
return parent::model($className);
}
public function tableName()
{
return 'BD_store_'.$this->store.'.products';
}
...}
Pour l’instant ça fonctionne mais je n’ai pas fait beaucoup de tests.
Par rapport à la proposition, je préfère éviter que la configuration se retrouve dans la classe spécifique. Il me semble flexible et suffisamment efficace de passer par un "component":
public function getDbConnection() {
$store = Yii::app()->user->getState('Store');
return Yii::app()->getComponent('db_'.$store);
}
Ceci nécessite alors d’avoir autant de configurations de base de données qu’il y a des boutiques. Au lieu de
'db'=>array(...)
il faut écrire
'db_store1'=>array(...)
.
Mon deuxième réflexe est d’éviter d’avoir une connaissance spécifique concernant comment on récupère le nom de la boutique dans cette classe. J’ajouterai une classe supplémentaire:
class Store extends CComponent {
public static function getCurrentStoreDb() {
$store = Yii::app()->user->getState('Store');
return self::getStoreDb($store);
}
public static function getStoreDb($store=null) {
$db=Yii::app()->getComponent('db_'.$store);
if($db===null)
throw new CException(Yii::t('app','Unknown store "{store}"',array('{store}'=>$store)));
else
return $db;
}
}
et ensuite:
public function getDbConnection() {
return Store::getCurrentStoreDb();
}
Ceci facilite les évolutions futures et permet d’organiser les spécificités concernant Store dans cette classe.