Uno de los temas que Yii tiene bien resueltos, y en cambio a todos los usuarios nos cuesta mucho montarlo y entenderlo son las relaciones entre tablas. En este post vamos a intentar aclarar un poco el tema, y dar algunas soluciones cuando la relación puede no cumplirse.
Vamos a presentar nuestro ejemplo. En las tablas que aparecen a continuación, hay una columna en tbl_fotos : «id_geopunto» que puede estar llena o no, y si esta llena , es la clave con la que podemos acceder a tbl_geopuntos
Definimos que cada foto puede tener como máximo un geopunto, y para ello indicamos en TblFotos.php:
public function relations() {
return array(
...,
'idGeopunto' => array(self::BELONGS_TO, 'TblGeopuntos', 'id_geopunto'),
...,
);
}
Con esto le estamos diciendo que idGeopunto es un puntero para alcanzar un registro de TblGeopuntos (el modelo), por medio de la columna id_geopunto.
Con la utilización de BELONGS_TO, estamos indicando que la columna de esta tabla apunta a la clave primaria de la otra, de alguna forma esta tabla es hija de tbl_geopuntos…
Hasta ahi, todo va bien, en el otro modelo, deberemos indicar HAS_MANY. Por lo que en TblGeopuntos pondremos:
public function relations() { return array( ...., 'fotosGeopunto'=> array(self::HAS_MANY,'TblFotos','id_geopunto'), ..., ); }
Pero eso será otra historia. En este articulo, nos vamos a centrar en la utilizacion de TblFotos, y como hemos añadido una relación, puede que nos interese crear su label, para mantener la estructura….
public function attributeLabels() { return array( 'id' => Yii::t('app', 'ID'), 'id_galeria' => Yii::t('app', 'Id Galeria'), 'id_geopunto' => Yii::t('app', 'Id Geopunto'), 'titulo' => Yii::t('app', 'Titulo'), 'descripcion' => Yii::t('app', 'Descripcion'), 'pie' => Yii::t('app', 'Pie'), 'url' => Yii::t('app', 'Url'), ... 'idGaleria' => null, 'idGeopunto' => null, 'tblFotosTextoses' => null, ); }
Vamos a ver como hacemos aparecer esta relación en un GridView. Suponiendo que queramos presentar la columna «sTitulo» de la tabla TblGeopuntos, tendríamos que escribir:
'columns'=>array(
array('name'=>'id','htmlOptions'=>$claseNumero),
...
array('name'=>'id_geopunto',
'value'=>'$data->idGeopunto->sTitulo',
'htmlOptions'=>$claseTexto),
...,
Y realmente, con esto ya conseguiríamos obtener el sTitulo, pero tendríamos un problema cuando no hubiéramos rellenado la columna id_geopunto, porque, por ejemplo, esa imagen no este asociada a un geopunto.
Hay varias formas de solucionar el problema, nosotros hemos optado por una que respeta la estructura de Yii y no exige registros auxiliares, se trata de mostrar la columna solamente cuando su valor sea superior a 0. Para ello, cambiamos el valor en el GridView
'columns'=>array(
array('name'=>'id','htmlOptions'=>$claseNumero),
...
array('name'=>'id_geopunto',
'value'=>'$data->id_geopunto==0?"...":$data->idGeopunto->sTitulo',
...,
Si os fijáis, lo que presentamos como valor es tres puntos («…») o el valor de la columna titulo ($data->idGeopunto->sTitulo) segun nuestra columna tenga cero o no
8 comentarios
Muchas gracias, resultó muy útil.
Gracias por el comentario