You are viewing revision #2 of this wiki article.
This is the latest version of this article.
You may want to see the changes made in this revision.
EN(http://www.yiiframework.com/wiki/413/) [ES]
A veces nos encontramos en circunstancias como ésta:
class TipoAnimal extends CActiveRecord {} // Tabla con los "tipos" de Animales
class Animal extends CActiveRecord { // Clase del modelo padre
// Modelo basado en una tabla con un campo: tipo_id
// que guarda el "tipo" de Animal
}
class Gato extends Animal {} // Clase hija
class Perro extends Animal {}
Y nos gustaría hacer algo como:
// Esta instrucción devuelve una clase "Gato"
$algunAnimal = Animal::model()->findByPk(1);
Ya que Yii implementa un modelo de desarrollo llamado "Factory", es muy fácil implementar una solución rápida a este escenario.
Paso 1 (y único) Sobrecargar la función instantiate(). Incluí los comentarios originales de la función CActiveRecord
/**
* 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 MiClase the active record
*/
protected function instantiate($attributes)
{
if (!isset($attributes['tipo_id'])) { // Cuando se crea and $tipo_id no se ha definido
return parent::instantiate($attributes);
}
$classRecord = AnimalType::model()->findByPk($attributes['tipo_id']); // Cargar el "Tipo"
if($classRecord === null)
throw new CException('Tipo de Animal no encontrado');
$className = $classRecord->nombre; // Asumiendo que el campo "nombre" almacena el nombre de la clase hija
$model = new $className(null); // El parámetro NULL es obligatorio
return $model;
}
Bastante sencillo, ¿verdad? A disfrutar y compartir :)
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.