Hace poco hablamos de CGridView, uno de los widgets más usados en Yii Framework. En este post veremos cómo incluir en un grid datos de varios modelos relacionados. Para ello usaremos el ejemplo del Blog que incluye el framework cuando lo descargas.

Vamos a ver en concreto cómo añadir al grid de Posts un campo del modelo User con el cual está relacionado. Por ejemplo el campo “username”, nombre de usuario del autor del post.

Lo primero que hay que hacer es declarar las relaciones ‘posts’ y ‘author’ en los modelos User y Post respectivamente:

[php]’posts’ => array(self::HAS_MANY, ‘Post’, ‘author_id’)[/php]

[php]’author’ => array(self::BELONGS_TO, ‘User’, ‘author_id’)[/php]

Los siguientes pasos los daremos en el modelo Post:

1.- Declararemos un atributo, por ejemplo “author_search”

[php]
class Post extends CActiveRecord
{

public $author_search;

}[/php]

2.- Incluiremos una regla que determine que este campo es seguro en “search” para que de esta forma se puedan realizar las comparaciones oportunas cuando se introduce algo en el buscador correspondiente del grid

[php]
public function rules()
{
return array(

array(‘author_search’, ‘safe’, ‘on’=>’search’),
);
}
[/php]

3.- Podemos, aunque no es necesario, especificar una etiqueta para el atributo nuevo, por ejemplo “Nombre autor”

[php]
public function attributeLabels()
{
return array(

‘author_search’ =>’Nombre autor’
);
}[/php]

4.- Por último hay que añadir varias cosas a la función search( )

– Añadiremos a criteria un “with” con la relación “author” para sacar en la consulta de los posts la información de éstos junto con la de los usuarios relacionados, en esta  información estará también la del campo “username” que es la que nos interesa:

[php]$criteria->with = array(‘author’);[/php]

– Para poder realizar búsquedas según el “username” del autor del post añadiremos la siguiente comparación:

[php] $criteria->compare(‘author.username’, $this->author_search, true ); [/php]

– Para poder ordenar por el “username” del autor añadimos en el atributo sort del CActiveDataProvider:

[php]
‘attributes’=>array(

‘author_search’=>array(
‘asc’=>’author.username ASC’,
‘desc’=>’author.username DESC’,
),

‘*’,

),[/php]

Para que quede claro la función search( ) resultaría de la siguiente manera:

[php]
public function search()
{
$criteria=new CDbCriteria;
$criteria->with = array(‘author’);

$criteria->compare(‘title’,$this->title,true);

$criteria->compare(‘author.username’, $this->author_search, true );

return new CActiveDataProvider(‘Post’, array(
‘criteria’=>$criteria,
‘sort’=>array(
‘attributes’=>array(
‘author_search’=>array(
‘asc’=>’author.username ASC’,
‘desc’=>’author.username DESC’,
),
‘*’,
),
‘defaultOrder’=>’status, update_time DESC’,
),
));
}
[/php]

Lo único que faltaría es añadir en el grid el atributo nuevo:

[php]
array(
‘name’=>’author_search’,
‘value’ => ‘$data->author->username’,
),
[/php]

Añadido campo de modelo relacionado

Para más información acerca de cómo usar Active Record (AR) para seleccionar datos de tablas relacionadas podéis consultar este enlace de la documentación oficial.

2 Replies to “Modelos relacionados en un CGridView”
  1. Teresa, genial artículo.

    Tengo una duda, ¿por qué tras hacer $model->attributes=$_POST[‘Post’] ($model=new Post) si hago un print_r($model->attributes) no veo el campo author_search?

    Muchísimas gracias.

  2. pregunta ¿cómo haría si quisiera mostrar una tabla con los post y las categorías asociadas a cada uno? gracias

Deja un comentario

*