I have Yii application and two tables with same structure tbl and tbl_history:
Now want to create model so it will select table by parameter I send when calling model. For example:
MyModel::model('tbl')->find();
//and
MyModel::model('tbl_history')->find();
Find related article with solution in Yii forum. Made same changes and finally got this in MyModel:
private $tableName = 'tbl'; // <=default value
private static $_models=array();
private $_md;
public static function model($tableName = false, $className=__CLASS__)
{
if($tableName === null) $className=null; // this string will save internal CActiveRecord functionality
if(!$tableName)
return parent::model($className);
if(isset(self::$_models[$tableName.$className]))
return self::$_models[$tableName.$className];
else
{
$model=self::$_models[$tableName.$className]=new $className(null);
$model->tableName = $tableName;
$model->_md=new CActiveRecordMetaData($model);
$model->attachBehaviors($model->behaviors());
return $model;
}
}
Now when I make:
echo MyModel::model('tbl_history')->tableName(); // Output: tbl_history
It returns right value, but:
MyModel::model('tbl_history')->find();
still returns value for tbl.
Added:
public function __construct($id=null,$scenario=null){
var_dump($id);
echo '<br/>';
parent::__construct($scenario);
}
and got:
string(tbl_history)
string(tbl_history)
NULL
It means Yii makes call to model from other place but don't know from where and how to prevent it.
Also It makes 2 calls to model, is it too bad for performance?
It looks like the CActiveRecord::getMetaData()
method needs to be overridden to achieve what you are looking for.
<?php
class TestActiveRecord extends CActiveRecord
{
private $tableName = 'tbl'; // <=default value
private static $_models=array();
private $_md;
public function __construct($scenario='insert', $tableName = null)
{
if($this->tableName === 'tbl' && $tableName !== null)
$this->tableName = $tableName;
parent::__construct($scenario);
}
public static function model($tableName = false, $className=__CLASS__)
{
if($tableName === null) $className=null; // this string will save internal CActiveRecord functionality
if(!$tableName)
return parent::model($className);
if(isset(self::$_models[$tableName.$className]))
return self::$_models[$tableName.$className];
else
{
$model=self::$_models[$tableName.$className]=new $className(null);
$model->tableName = $tableName;
$model->_md=new CActiveRecordMetaData($model);
$model->attachBehaviors($model->behaviors());
return $model;
}
}
public function tableName()
{
return $this->tableName;
}
/**
* Returns the meta-data for this AR
* @return CActiveRecordMetaData the meta for this AR class.
*/
public function getMetaData()
{
if($this->_md!==null)
return $this->_md;
else
return $this->_md=static::model($this->tableName())->_md;
}
public function refreshMetaData()
{
$finder=static::model($this->tableName());
$finder->_md=new CActiveRecordMetaData($finder);
if($this!==$finder)
$this->_md=$finder->_md;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With