Yii Models: Using dynamic table name in a Yii model

Arfeen picture Arfeen · Apr 17, 2012 · Viewed 10k times · Source

I have a Yii model that will be using (later) multiple databases and the table prefix will be based on a code.

For example:

AMI_tablename, BMI_ AMI_tablename etc

These all tables are same but in different databases.

I want to know how could I provide the dynamic table name to Yii model at run time?

I tried to using a setter function but the parent class CActiveRecord gives an error as it does not get the value from the child model class.

so here is my model code (only the part I have problem)

class RevShareModel extends CActiveRecord
{

    public $prefix;

    public static function model($className=__CLASS__)
    {
        return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return $this->prefix . '_revshare_model';
    }

now somewhere in my controller

$obj = RevShareModel::model();
$obj->prefix ="BMI";
$obj->tableName();
$obj->findByPk(1);

exit;

But what I get the error is:

CDbException

The table "_revshare_model" for active record class "RevShareModel" cannot be found in the database.

C:\wamp\www\framework\db\ar\CActiveRecord.php(2264)

seems like when tableName() method is called by CActiveRecord it does not get $prefix.

Answer

katsanva picture katsanva · Nov 13, 2013

You've got such error because the table name is actually stored in model's metadata. You can see that by checking contents of $model->getMetaData() which returns CActiveRecordMetaData object. To refresh metadata you should call $model->refreshMetaData() after changing the 'prefix' attribute of your model, e.g.:

...
$obj->prefix ="BMI";
$obj->refreshMetadata();
...

This will definitely do the trick.