Puigcerber
Puigcerber

Reputation: 10114

Yii strange behavior: CGridView + group + with

I'm having an strange behavior which I'm going to try to explain.

I'm building a reporting system where every user can have their profile, pictures or messages being reported by other users.

In the backend I want to show a CGridView where every user appears in a row with the total amount of times has been reported.

To do that I'm adding group to the criteria and it works good.

But if I want to filter the view by any related field, I have to add with to the criteria and it works good with the filtering or the search, but the total display of results is incorrect showing Displaying 1-2 of 15 result(s) when it should show Displaying 1-2 of 2 result(s) as in the report table I have 15 rows but only two users, adding also a nonexistent pagination.

models/Report.php

public function relations()
{
    return array(
        'reported' => array(self::BELONGS_TO, 'User', 'reported_id'),
    );
}

public function search()
{
    $criteria = new CDbCriteria();
    $criteria->select = array(
        '*',
        'count(*) as reports_count',
    );
    $criteria->group = 't.reported_id';
    $criteria->with = array('reported');

    return new CActiveDataProvider($this, array(
        'criteria' => $criteria,
        'sort'=>array(
            'attributes'=>array(
                'status_search'=>array(
                    'asc'=>'reported.user_status_id',
                    'desc'=>'reported.user_status_id DESC',
                ),
                'reports_count' => array(
                    'asc' => 'reports_count ASC',
                    'desc' => 'reports_count DESC',
                ),
                '*',
            ),
        ),
        ));
} 

Update: I found the solution using join instead of with and selecting the fields I need instead of selecting all of them with *:

$criteria->select = array(
        't.id, t.reported_id',
        'count(*) as reports_count',
    );
$criteria->group = 't.reported_id';
$criteria->join = 'LEFT JOIN user u on u.id = t.reported_id';

Upvotes: 4

Views: 2744

Answers (2)

Roey B
Roey B

Reputation: 53

I found it on yii's forum, posted by a user named "bennouna". It did the trick for me.

public function groupedSearch() {
  $criteria = new CDbCriteria;
  $criteria->select = '…';
  $criteria->with = array(…);
  $criteria->group = '…';
  $dp = new CActiveDataProvider($this, array('criteria'=>$criteria));
  $dp->setTotalItemCount(count($this->findAll($criteria)));
  return $dp;
}

Upvotes: 3

sucotronic
sucotronic

Reputation: 1504

When using a CActiveDataprovider YII doesn't use the 'with' established in the criteria to do the 'totalItemCount' so it'll say total number of results without with. I recommend you to add join conditions by hand to overcome this :)

$criteria->join = 'left join User u on u.id=t.reported_id'

And remove the $criteria->select and use the 'totalItemCount' method of the CActiveDataProvider.

Upvotes: 4

Related Questions