relational CSort

Hello guys,

i cannot get my sorting wroking for relational fields. sorting on the other field is working fine.

thank you.

Model:


    public function relations() {

        return array(

            'rCity' => array(self::BELONGS_TO, 'City', 'CityId', 'alias' => 'rCity'),

View:


<th><?php echo $sort->link('rCity.City'); ?></th>

Controller:


        $sort->attributes = array(

            'Daytrip.IdDaytrip' => 'IdDaytrip',

            'Daytrip.Daytrip' => 'Daytrip',

            'rCity.City' => 'City',

            'Daytrip.Modified' => 'Modified'

        );

CSort was changed since 1.1 beta. Please check the latest CSort API on how to use it.

got it working now:

model:


    public function relations() {

        return array(

            'rCity' => array(self::BELONGS_TO, 'City', 'CityId'),

view:


<th><?php echo $sort->link('City', 'City'); ?></th>

controller:


        $sort = new CSort('Daytrip');

        $sort->multiSort = false;

        $sort->attributes = array(

            'IdDaytrip' => 'IdDaytrip',

            'Daytrip' => 'Daytrip',

            'City' => 'rCity.City',

            'Modified' => 'Modified'

        );

        $sort->defaultOrder = 'IdDaytrip ASC';

        $sort->applyOrder($criteria);

but why is yii not translating City to Plaats (dutch)? (all the fieldnames are translated)

model:


    public function attributeLabels() {

        return array(

            'City' => Yii::t('labels', 'City'),

messages.php:


<?php

return array (

    'City' => 'Plaats',

Add the above to the primary model.

Edit:

Framework ought to have a cleaner way to handle this.

/Tommy


    public function attributeLabels()

    {

        return array(

            'City' => Yii::t('labels', 'City'),

is located in the Models Daytrip and City, but still not working

I see, perhaps it’s not good for 1.1.

/Tommy

In 1.1, you may specify the label via CSort::attributes. Please check the API for this property for more details.

Something seems to be wrong with CSort->attributes in 1.1.

(example: ‘From’ virtual attribute, ‘FromLocation’ model attribute)

Simple case:

(translation from attributeLabels in effect)




1) array() // every attribute sortable

2) array('FromLocation') // FromLocation sortable, other attributes responds in GET param

3) array('From'=>'FromLocation') // not recognized, other attributes responds in GET param

4) array('FromLocation'=>'From') // (1.0 style) generates error

5) array('FromLocation'=>'FromLocation') // see (2)



Extended case:

(translation from attributeLabels except when ‘label’ is specified’)




5) array('From'=>array('asc'=>'FromLocation', 'desc'=>'FromLocation DESC')), // see (3) 

6) array('FromLocation'=>array('asc'=>'From', 'desc'=>'From DESC')), // see (4)

7) array('FromLocation'=>array('asc'=>'FromLocation', 'desc'=>'FromLocation DESC', 'label'=>'Other label')), //works, see (2)



GET (sort) param is always model attribute in 1.0, it used to be the value part, e.g ‘From’ in (4).

What would be the purpose of ‘DESC’?

The API doc may need some attention, especially second paragraph

Edit:

Relational cases:

(translation from attributeLabels in primary model except when ‘label’ is specified’)




<img src='http://www.yiiframework.com/forum/public/style_emoticons/default/cool.gif' class='bbc_emoticon' alt='8)' /> array('From'=>array('asc'=>'relation.FromLocation', 'desc'=>'relation.FromLocation DESC')), // see (3)

9) array('relation.FromLocation'=>array('asc'=>'relation.FromLocation', 'desc'=>'relation.FromLocation DESC')), // see (3)

10) array('FromLocation'=>array('asc'=>'relation.FromLocation', 'desc'=>'relation.FromLocation DESC')), // works, see (2)



/Tommy

Hello,

  I have the same problem bas_vdl commented in the beggining, then I copied his solution and still doesn't work.

Controller:




     $sort= new CSort('Foro');

     $sort->multiSort = false;

     $sort->attributes = array('titulo' => 'titulo',

                               'fechaCreacion' => 'fechaCreacion',

                               'ultRespNumero'=> 'ultimaRespuesta.numero',

			       'ultRespFechaCreacion' => 'ultimaRespuesta.fechaCreacion',

 				  );

    $sort->defaultOrder = 'fechaCreacion DESC';

    $sort->applyOrder($criteria);



Model:




    public function relations(){

	return array(

	             'categoria' => array(self::BELONGS_TO, 'Categoria', 'idCategoria'),

	             'usuario' => array(self::BELONGS_TO, 'Usuario', 'idUsuario'),

		     'ultimaRespuesta' => array(self::BELONGS_TO, 'Respuesta', 'idUltimaRespuesta'),

	             'respuestas' => array(self::HAS_MANY, 'Respuesta', 'idForo', 'order'=>'fechaCreacion DESC'),

		);

	}



View:




    echo $sort->link("ultRespFechaCreacion",'&Uacute;ltima respuesta');

    echo $sort->link("ultRespNumero",'Respuestas');



Even I tried with the new $sort->attributes specification way:




    $sort->attributes = array('titulo' => 'titulo',

			      'fechaCreacion' => 'fechaCreacion',

		              'ultRespNumero'=>array(

				                    'asc'=>'ultimaRespuesta.numero',

	                                            'desc'=>'ultimaRespuesta.numero DESC',

   						    'label'=>'Respuestas'

							),		

			      'ultRespFechaCreacion'=>array(

   							'asc'=>'ultimaRespuesta.fechaCreacion',

							'desc'=>'ultimaRespuesta.fechaCreacion DESC',

							'label'=>'Ultima respuesta'

							      )

			);



The grid is showed, but when I click in the column header of ultRespNumero or ultRespFechaCreacion I get a CDbException. Then I printed the SQL that it tryed to execute and found the follow (obviosly wrong statement):

SELECT * FROM Foro t WHERE idCategoria=7 ORDER BY ultimaRespuesta.numero LIMIT 15

I hope can help me. Thank you in advance.

My guess is…

The SQL seems to suggest that you are using lazy loading. You have to use eager loading.

Needs a “with->array(‘ultimaRespuesta’)” somewhere.

Can’t tell without more of your code. How are you creating your CActiveDataProvider?

If this forum disapproves of reviving months-old threads then I apologize.

I believe I’m having the same issue as Damian. The SQL I’m getting simply isn’t what it needs to be and it seems like CSort is ignoring the alias relational option:

meanpenguin’s post seems to be close to the heart of the matter, but where would the ‘with’ option get set and on what object? It seems like the relations are meant to take care of this need. My code follows, and any suggestions are appreciated:

In GameStub Model:




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_merge(

      array(

         'game' => array( self::BELONGS_TO, 'Game', 'game_id', 'alias' => 'Game' ),

      ),

      parent::relations()

   );

}

Note that the array_merge is part of an implementation of an extension of CActiveRecord that I made, which GameStub extends - it should have no effect on how relations work and has proven not to thus far.

in GameStubController:




public function actionIndex()

{

   // Select only entries that are for our $model

   $oCriteria = new CDbCriteria( array(

                                      //'condition' => '',

                                      //'order'     => 'time ASC',

                                   )

                                 );


   $oSorter = new CSort('GameStub');


   $oSorter->separators = array(':','-');

   $oSorter->attributes = array( 

      'priority'       => 'priority',

      'desired_pct'    => 'desired_pct',

      'confidence_pct' => 'confidence_pct',

      'biz_status'     => 'biz_status',

      'boots'          => 'boots',

      'addendum'       => 'addendum',

      'name'           => 'game.name'

      /*

      'name' => array(

         'asc'   => 'game.name ASC',

         'desc'  => 'game.name DESC',

         'label' => 'Title',

      ),

      'metascore' => array(

         'asc'   => 'game.metascore ASC',

         'desc'  => 'game.metascore DESC',

         'label' => 'MetaCritic Rating',

      ),

      */

   );


   $oSorter->multiSort = false;

   $oSorter->defaultOrder = array( 'priority' => true );


   // Create the data provider for the view

   $oDataProvider = new CActiveDataProvider( 'GameStub',

                                            array(

                                               'pagination' => false,

                                               'criteria'   => $oCriteria,

                                               'sort'       => $oSorter,

                                            ));


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

      'dataProvider' => $oDataProvider,

      'oSorter'      => $oSorter,

   ));

}

And finally, in my view:




echo $oSorter->link( 'name' );


$this->widget('application.extensions.nlistview.NListView', array(

      'dataProvider'       => $dataProvider,

      'itemView'           => '_stub',

      'itemsCssClass'      => 'listView',

      'sItemsContainerTag' => 'ul',

      'template'           => '{summary}{sorter}{pager}{items}{pager}',

      'enableSorting'      => true,

      'sortableAttributes'=>array(

         'priority',

         'desired_pct',

         'confidence_pct',

         'biz_status',

         'boots',

         'addendum',

         'name',

         //'GameStub.metascore',

      ),

   ));

Changed my actionIndex() to hold the following:




$oCriteria = new CDbCriteria( array(

                                'with' => 'game',

                             ));


$oSorter = new CSort('GameStub');

$oSorter->attributes = array( 

   'priority'       => 'priority',

   'desired_pct'    => 'desired_pct',

   'confidence_pct' => 'confidence_pct',

   'biz_status'     => 'biz_status',

   'boots'          => 'boots',

   'addendum'       => 'addendum',


   'game.name' => array(

      'asc'   => 'game.name ASC',

      'desc'  => 'game.name DESC',

      'label' => 'Title',

   ),

);

$oSorter->multiSort = false;

$oSorter->defaultOrder = array( 'priority' => true );


$oDataProvider = new CActiveDataProvider( 'GameStub',

                                         array(

                                            'pagination' => false, 

                                            'criteria'   => $oCriteria,

                                            'sort'       => $oSorter,

                                         ));



Now the sort link for game appears as ‘Title’ as it should and doesn’t error, but it doesn’t actually sort at all either. Does anyone have any ideas or is CSort missing some functionality?

I guess there is little interest in this topic but I just updated to 1.1.5 today as I saw there was a refactor of CActiveFinder and some classes related to my issue, but the problem persists so far.