Duda con AR, CGridView y campo relacionado

Hola a todos,

Tengo la siguiente duda.

Estoy comenzando hace poco con este super framework y con AR.

Tengo 2 modelos: Application e Indicator donde una Application puede tener uno o mas Indicator.

Mi problema es en el código de la vista admin generado con gii para el modelo Indicator .

Vista admin para modelo Indicator:




<?php $this->widget('zii.widgets.grid.CGridView', array(

	'id'=>'indicator-grid',

	'dataProvider'=>$model->search(),

	'filter'=>$model,

	'columns'=>array(

		'id',

		'applicationId',

		'tag',

		'name',

		array(

			'class'=>'CButtonColumn',

		),

	),

)); ?>



En este caso yo quisiera que en vez de applicationId, se mostrara el nombre de la aplicación.

Buscando ejemplos en el foro encontré la solución para una para un widget CDetailView, la cual me funcionó de maravillas.

Vista view para modelo Indicator:




<h1>View Indicator</h1>


<?php $this->widget('zii.widgets.CDetailView', array(

	'data'=>$model,

	'attributes'=>array(

		'id',

		array( 

                    'label'=>'Application',

                    'value'=>$model->application->tag,

                ),

		'tag',

		'name',

	),

)); ?>



Entonces traté de hacer lo mismo para el widget CGridView, de esta forma:

Vista admin para modelo Indicator:




<?php echo CHtml::link('Advanced Search','#',array('class'=>'search-button')); ?>

<div class="search-form" style="display:none">

<?php $this->renderPartial('_search',array(

	'model'=>$model,

)); ?>

</div><!-- search-form -->


<?php $this->widget('zii.widgets.grid.CGridView', array(

	'id'=>'indicator-grid',

	'dataProvider'=>$model->search(),

	'filter'=>$model,

	'columns'=>array(

		'id',

		array( 

            'label'=>'Application',

            'value'=>$model->application->tag,

        ),

		'tag',

		'name',

		array(

			'class'=>'CButtonColumn',

		),

	),

)); ?>



Y ahí me aparece el error:

PHP Error

Description

Trying to get property of non-object

Si alguien me puede aportar ideas sobre qué esta fallando bienvenido sea!

(Apache/2.2.11 (Win32) PHP/5.3.0 Yii Framework/1.1.2)

Saludos y gracias!

Hola!

Te paso un ejemplo. La diferencia que la valor de "value" es una expresión entre comillas que PHP evalúa, y la variable a la que hace referencia no es $model sino $data:




<?php $this->widget('zii.widgets.grid.CGridView', array(

	'id' => 'comentario-grid',

	'dataProvider' => $model->search(),

	'filter' => $model,

	'filterPosition' => false,

	'enableSorting' => false,

	'columns' => array(

		'fecha' => array(

			'header' => 'Fecha',

			'name' => 'fecha',

			'value' => '$data->fecha',

		),

		'nombre' => array(

			'header' => 'Nombre',

			'name' => 'nombre',

			'value' => '$data->nombre',

		),

		'pais_id' => array(

			'header' => 'País',

			'name' => 'pais_id',

			'value' => '$data->pais->nombre',

		),

		'activo' => array(

			'name' => 'activo',

			'value' => '$data->activo ? "Sí" : "No"',

			'header' => 'Activo'

		),

	),

)); ?>



Fijáte en la API se explica bien: http://www.yiiframework.com/doc/api/CDataColumn#value-detail

Saludos!

Hola Luciano,

Gracias por la pronta respuesta!

Funcionó muy bien el ejemplo, la única duda que tengo es en qué parte la variable $data toma su valor, ya que en el controlador veo que se está pasando solo $model a la vista.

Sería entonces $data una variable interna del widget en jquery? Lo consulto porque es un poco confuso para mí.

Gracias por la ayuda!

Saludos,

Controlador, accion: admin




	/**

	 * Manages all models.

	 */

	public function actionAdmin()

	{

		$model=new Indicator('search');

		if(isset($_GET['Indicator']))

			$model->attributes=$_GET['Indicator'];


		$this->render('admin',array(

                    'model'=>$model,

		));

	}



Vista admin funcionando:




<?php $this->widget('zii.widgets.grid.CGridView', array(

	'id'=>'indicator-grid',

	'dataProvider'=>$model->search(),

	'filter'=>$model,

	'columns'=>array(

		'id',

		'applicationId' => array(

                    'header'=>'Application',

                    'name'=> 'applicationId',

                    'value'=> '$data->application->tag',

                ),

		'tag',

		'name',

		array(

			'class'=>'CButtonColumn',

		),

	),

)); ?>



Creo que no tienes que hacer todo eso, puedes usar las relaciones directamente como te indica el ejemplo del api… http://www.yiiframework.com/doc/api/CGridView

prueba con esto:


<?php $this->widget('zii.widgets.grid.CGridView', array(

        'id'=>'indicator-grid',

        'dataProvider'=>$model->search(),

        'filter'=>$model,

        'columns'=>array(

                'id',

                'application.tag',// {nombre de la relacion}.{attributo}

                'tag',

                'name',

                array(

                        'class'=>'CButtonColumn',

                ),

        ),

)); ?>

Asgaroth,

Probé ese código y lo que pasó fue que en la tabla se desactivó el input para hacer búsqueda en la columna.

BTW: En el link de la documentación http://www.yiiframework.com/doc/api/CGridView hay un tipo que pregunta lo mismo que yo: “Can you tell me what variable is $data????

Saludos y gracias por la ayuda!

Hola, la variable data es en cada iteracion el modelo actual. es decir si estas haciendo un CGridView para un CDataProvider que devuelve en tu caso "indicator"s la variable data es uno de esos indicators puede acceder a sus atributos y metodos.

Para activar el input para hacer la busqueda creo que si tienes que usar el array, especificando el name y el value creo, o configurando el filter adecuadamente, no recuerdo exactamente.

Muchas gracias por sus respuestas, me han orientado bastante, por mi parte el tema queda resuelto.

Saludos!

Claudio

Hola Claudio, justo estaba intentando hacer lo mismo, tu post me vino muy bien.

El problema es que cuando ordeno la columna en realidad lo hace en base al id del campo y no al nombre, alguien puede orientarme un poco, igualmente voy a seguir buscando en el foro.

Saludos

Hola!

Este post te va a ayudar, creo :)

http://www.yiiframework.com/forum/index.php?/topic/9714-sort-user-defined-column-in-cgridview/

saludos

Muchas gracias Horacio, era una duda que tenía por resolver! ya lo guardé para cuando lo necesite

Hola comunidad

tengo un problema (desde que pase a php 5.3)

mi codigo funcionaba bien en php 5.2, pero ahora no, el problema esta en las relaciones que pueden ser nulas (opcionales)

en mi caso el ultimo usuario que modifico el registro

(la relacion ‘usu_mod’)

el error:

alguien me da una mano?

en la vista tengo




<?php $this->widget('zii.widgets.grid.CGridView', array(

    'id'=>'ticket-grid',

    'dataProvider'=>$model->search(),

    'filter'=>$model,

        'summaryText'=>'Mostrando {start}-{end} de {count}',

    'columns'=>array(

        //'id_ticket',

        'fecha',

        'nombre',

                array('name'=>'id_sector','sortable'=>'true','value'=>'$data->sector->descripcion'),


        //'id_sector',

        //'id_tecnico',

                array('name'=>'id_tecnico','sortable'=>'true','value'=>'$data->tecnico->descripcion'),

        //'id_estado',

        array('name'=>'id_estado','sortable'=>'true','value'=>'$data->estado->descripcion'),

        'obs',

        

        //'id_usuario',

                array('name'=>'id_usuario','sortable'=>'true','value'=>'$data->usuario->usuario'),

        'timestamp',

                array('name'=>'id_usu_mod','sortable'=>'true','value'=>'$data->usu_mod->usuario'),

        'fecha_mod',

        

        array(

            'class'=>'CButtonColumn',

        ),

    ),

)); ?>




en el model





...

    public function relations()

    {

        return array(


                'usuario' => array(self::BELONGS_TO, 'Usuarios', 'id_usuario'),

                'usu_mod' => array(self::BELONGS_TO, 'Usuarios', 'id_usu_mod'),

                'sector' => array(self::BELONGS_TO, 'Sector', 'id_sector'),

                'estado' => array(self::BELONGS_TO, 'Estado', 'id_estado'),

                'tecnico' => array(self::BELONGS_TO, 'Tecnico', 'id_tecnico'),

        );

    }





...

    public function search()

    {


  $sort = new CSort();

  

  $sort->attributes = array(

   'id_ticket',

   'fecha'=>array(

      'asc'=>'t.fecha',

      'desc'=>'t.fecha desc',

    ),


   'nombre'=>array(

      'asc'=>'t.nombre',

      'desc'=>'t.nombre desc',

    ),


   'id_sector'=>array(

      'asc'=>'sector.descripcion',

      'desc'=>'sector.descripcion desc',

    ),

   'id_tecnico'=>array(

      'asc'=>'tecnico.descripcion',

      'desc'=>'tecnico.descripcion desc',

    ),

   'id_estado'=>array(

      'asc'=>'estado.descripcion',

      'desc'=>'estado.descripcion desc',

    ),


   'obs'=>array(

      'asc'=>'t.obs',

      'desc'=>'t.obs desc',

    ),


   'id_usuario'=>array(

      'asc'=>'usuario.nombre',

      'desc'=>'usuario.nombre desc',

    ),

   'id_usu_mod'=>array(

      'asc'=>'usu_mod.nombre',

      'desc'=>'usu_mod.nombre desc',

    ),

   'timestamp'=>array(

      'asc'=>'t.timestamp',

      'desc'=>'t.timestamp desc',

    ),

   'fecha_mod'=>array(

      'asc'=>'t.fecha_mod',

      'desc'=>'t.fecha_mod desc',

    ),




  );




        $criteria=new CDbCriteria;

                $criteria->addCondition('t.borrado=0');


                $sort->defaultOrder = 't.timestamp DESC';


                $criteria->with=array('sector','usuario','usu_mod','estado','tecnico');

        $criteria->compare('t.id_ticket',$this->id_ticket);


        $criteria->compare('t.fecha',$this->fecha,true);


        $criteria->compare('t.nombre',$this->nombre,true);


        $criteria->compare('sector.descripcion',$this->id_sector,true);


        $criteria->compare('tecnico.descripcion',$this->id_tecnico,true);


        $criteria->compare('estado.descripcion',$this->id_estado,true);


        $criteria->compare('t.obs',$this->obs,true);


        $criteria->compare('usuario.nombre',$this->id_usuario);

        $criteria->compare('usu_mod.nombre',$this->id_usu_mod);

                

                $criteria->compare('t.fecha_mod',$this->fecha_mod,true);


        $criteria->compare('t.timestamp',$this->timestamp,true);


        return new CActiveDataProvider('Ticket', array(

            'criteria'=>$criteria,

                        'sort'=>$sort,

        ));

    }




bueno, no se si es "la solucion !"

pero funciona




    public function actionAdmin()

    {

        $model=new Ticket('search');

        if(isset($_GET['Ticket']))

            $model->attributes=$_GET['Ticket'];


        error_reporting(E_ALL ^ E_NOTICE);


                $this->render('admin',array(

            'model'=>$model,

        ));

    }




esta creo que es la solución




array('name'=>'id_sector','sortable'=>'true','value'=>'($data->sector)?$data->sector->descripcion:"Sin Sector"'),



gracias zaccaria