XAKEPEHOK
@XAKEPEHOK

Yii: Ошибка пагинации при together = true. Как исправить?

Бьюсь уже третьи сутки. Гуглил до тошноты. Будьте добры, направьте в нужно русло.


Ситуация: на сайте есть пользователи. Пользователи имеют определенные характеристики, которые хранятся в связанных таблицах. Нужно найти пользователей, соответствующих определенным характеристикам.


Проблема: отражена ниже на скриншотах

Модель Users
public function relations() {
    return array(
        'usersMotivations' => array(self::HAS_MANY, 'UsersMotivations', 'userID'),
    );
}


Действие контроллера
public function actionIndex() {
    $criteria = new CDbCriteria;
    $criteria->with = array('usersMotivations');
    $criteria->addInCondition('motivationID',array(1,2));
    $criteria->together = true;

    $dataProvider = new CActiveDataProvider('Users',array(
        'criteria'=>$criteria,
        'pagination'=>array('pageSize'=>10)
    ));

    $this->render('index', array( 'dataProvider' => $dataProvider));
}


Представление
$this->widget('zii.widgets.CListView', array(
    'dataProvider'=>$dataProvider,
    'itemView'=>'_view',
));



И вот здесь происходит самое интересное. При 'pagination'=>array('pageSize'=>10) страница с результатами выглядит так:
bb5ce3698415f2955f4134eb48287747.png


При 'pagination'=>array('pageSize'=>2) один из результатов дублируется на двух страницах
a1b9d356191849f2b23bed14adfd1a8a.png


Теперь если убрать строку $criteria->addInCondition('motivationID',array(1,2)); то один из результатов дублируется, а другой — исчезает вообще
f5cac9ee353b13cf17ebcae469ca483e.png


Опытным путем выяснил, что виной всему $criteria->together = true; и если его убрать, то с пагинацией становится все нормально, но тогда перестает работать условие поиска
$criteria->addInCondition('motivationID',array(1,2));



Как быть, подскажите пожалуйста?
  • Вопрос задан
  • 6227 просмотров
Решения вопроса 1
@Darivush
Попробуйте
$criteria->group='t.user_id';

где t.user_id PK модели Users.
Плюс т.к. у вас стоит задача не выбрать все мотивации у юзера можно сделать такой финт: добавить релейшен
'usersMotivation' => array(self::HAS_ONE, 'UsersMotivations', 'userID'),
И использовать тот же самый критерий
$criteria = new CDbCriteria;
$criteria->with = array('usersMotivation');
$criteria->addInCondition('motivationID',array(1,2));

если не ошибаюсь заработает даже без
$criteria->together = true;
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
EnChikiben
@EnChikiben
Это из-за связи один ко многим. Вам надо как то так:
public function actionIndex() {
    $criteria = new CDbCriteria;
$criteria->addCondition(" (SELECT COUNT(*) FROM `UsersMotivations` WHERE userID = t.ID AND `motivationID` IN (:motivationID)  ) > 0 ");
$criteria->params[":motivationID"] = implode(',',array(1,2));

    $dataProvider = new CActiveDataProvider('Users',array(
        'criteria'=>$criteria,
        'pagination'=>array('pageSize'=>10)
    ));

    $this->render('index', array( 'dataProvider' => $dataProvider));
}

Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы