unchanged
Title
Instantiate a child class that depends a type field from parent model class (CActiveRecord)
**[EN]** [[ES]](http://www.yiiframework.com/wiki/414/)
Sometimes we have an scenario like this:
~~~
[php]
class AnimalType extends CActiveRecord {} // Table with the "types" of
Animals available
class Animal extends CActiveRecord { // Parent model class
// Model based on a table with a field: type_id
// that stores the type of the Animal
}
class Cat extends Animal {} // Child class
class Dog extends Animal {}
~~~
And we'd like to do something like:
~~~
[php]
// This statement will return a "Cat" instance
$someAnimal = Animal::model()->findByPk(1);
~~~
Since Yii implements a factory design model, it's very easy to implement a
simple and quick solution for this.
**Step 1** (and unique)
Override **instantiate()** function.
_I included the PhpDoc comments present in CActiveRecord_
~~~
[php]
/**
* Creates an active record instance.
* This method is called by {@link populateRecord} and {@link
populateRecords}.
* You may override this method if the instance being created
* depends the attributes that are to be populated to the record.
* For example, by creating a record based on the value of a column,
* you may implement the so-called single-table inheritance mapping.
* @param array $attributes list of attribute values for the active records.
* @return MyClass the active record
*/
protected function instantiate($attributes)
{
if (!isset($attributes['type_id'])) { // When creating and $type_id has
not defined yet
return parent::instantiate($attributes);
}
$classRecord = AnimalType::model()->findByPk($attributes['type_id']);
// Load the "Type" class
if($classif($classRecord === null)
throw new CException('Type not found');
$className = $classRecord->name; // Let's assume that name is the
field storing the name of the class
$model = new $className(null); // Null param needed for populating the
record
return $model;
}
~~~
Very easy, right.
Enjoy and share :)
_If you find some grammar, spelling or language mistake, feel free to fix it or
report it to me. English is not my native language_