Programación

Relaciones en Yii

En este tema quiero mostrar el manejo de las claves foráneas en Yii framework mediante Active Record (AR).

Antes de usar AR para ejecutar consultas relacionales, necesitamos darle conocer a AR como una clase AR se relaciona con otra.

La relación entre dos clases AR está directamente asociada con la relación entre las tablas de la base de datos representadas por esas clases. Desde el punto de vista de la base de datos, una relación entre dos tablas A y B tiene tres tipos: uno-a-muchos (ej.: User y Post), uno-a-uno (ej.: User y Profile) y muchos-a-muchos (ej.: Category y Post). En AR, hay cuatro tipo de relaciones:

Declarar relaciones en AR involucra sobreescribir el método relations() de CActiveRecord. El método devuelve un arreglo de configuraciones de relaciones. Cada elemento del arreglo representa una sola relación con el siguiente formato:

'VarName'=>array('RelationType', 'ClassName', 'ForeignKey', ...additional options)

donde VarName es el nombre de la relación; RelationType especifica el tipo de relación, que puede ser una de las cuatro constantes: self::BELONGS_TOself::HAS_ONEself::HAS_MANY y self::MANY_MANY;ClassName es el nombre de la clase relacionada a ésta clase AR; y ForeignKey especifica la(s) clave(s) foránea(s) involucrada(s) en la relación. Pueden ser especificadas opciones adicionales al finad de cada relación (será descripto luego).

El siguiente código muestra como declarar las relaciones para las clases User y Post.

class Post extends CActiveRecord
{
    public function relations()
    {
        return array(
            'author'=>array(self::BELONGS_TO, 'User', 'authorID'),
            'categories'=>array(self::MANY_MANY, 'Category', 'PostCategory(postID, categoryID)'),
        );
    }
}

class User extends CActiveRecord
{
    public function relations()
    {
        return array(
            'posts'=>array(self::HAS_MANY, 'Post', 'authorID'),
            'profile'=>array(self::HAS_ONE, 'Profile', 'ownerID'),
        );
    }
}

Ejemplo concreto (Productos y Categorias con sus modelos y crus creados con gii):

Modelo Productos:

public function relations()
 {
 // NOTE: you may need to adjust the relation name and the related
 // class name for the relations automatically generated below.
 return array(
 'categoria' => array(self::BELONGS_TO, 'Categorias', 'id_categoria'),
 //Prestar atención a esta parte, ya que "categoria" será usado para acceder a dicho modelo y hacer consultas de una forma sencilla.
 //El modelo Categorias tiene los siguientes campos: id_categoria (pk) y desc_categoria
 );
 }

– Por defecto Yii nos crea todas las relaciones cuando creamos el modelo, pero por ejemplo si agregamos una una tabla en nuestra base de datos podemos agregar la nueva relación manualmente.
– Por defecto también Yii crea los cruds pero no muestra el valor real de la FK, para poder mostrar los valores reales en las vistas (views), hacer lo siguiente:
view.php de Productos.


id_categoria', //Modificar esa linea por:

array(
 'name'=>'id_categoria',
 'value'=>$model->categoria->desc_categoria, //Con esto se mostrará la descripción de la categoría en vez del id_categoria
 ),

_view.php de Productos.

Cambiar la linea donde se encuentra id_categoria por:


<b><?php echo CHtml::encode($data->getAttributeLabel('id_categoria')); ?>:</b>
 <?php echo CHtml::encode($data->categoria->desc_categoria); ?>  //Con esto se mostrará la descripción de la categoría en vez del id_categoria
 <br />

admin.php de Productos.

Cambiar la linea donde se encuentra ‘id_categoria’, por:


array(
 'name'=>'id_categoria',
 'value'=>'$data->categoria->desc_categoria',  //Con esto se mostrará la descripción de la categoría en vez del id_categoria
 'filter'=>Categorias::getListCategorias(),    //Esto ya es un agregado, muestra un combobox con todas las categorias para poder filtrarlas, si no lo ponemos usa el id_categoria por defecto
 //Debemos de crear una función estática en el modelo Categorias que se llame getListCategorias(), esto es totalmente opcional
 ),

Agregar la función al modelo Categorias (models/Categorias.php) para usar el filtro en la vista admin.php y también para crear o actualizar nuevos Productos:


public static function getListCategorias()
 {
 return CHtml::listData(Categorias::model()->findAll(),'id_categoria','desc_categoria');
 }

Para crear o actualizar productos y que aparezca un combobox para elegir las categorías hacer lo siguiente:
Modificar el _form.php, justamente reemplazar la parte donde encontremos el id_categoria por el siguiente código:


<?php echo $form->labelEx($model,'id_categoria'); ?>
<?php echo $form->dropDownList($model,'id_categoria',Categorias::getListCategorias(),array('empty'=>'seleccione categoria'));
//Esto es lo agregado para mostrar el combobox, como verán usa la misma función estática  que agregamos en el modelo Categorias
?>

Espero les haya servido de utilidad este tema, lo pueden adaptar todo según sus necesidades, es por eso que puse un ejemplo concreto.

Por más información sobre el tema, visitar este link

Salir de la versión móvil