Как сделать сортировку связанных таблиц в Yii2?

Доброго времени суток!

Ребят, помогите, сбит с толку.

в общем есть 2 таблицы:
Товары (название, фото и т.д)
Остатки (цены, в каких магазинах есть и т.д)

Эти таблицы связаны, т.е на сайте вывожу продукт и его остатки.
А еще есть возможность выбрать магазин (и продукция на сайте выводится из этого магазина) храню id магазина в сессиях и при наличии сессии добавляю условие where().
Вывод такой:
Product::find()->joinWith('ostatki')->where(['ostatki.id' => $id])->orderBy(['ostatki.price' => SORT_ASC])->all();

Но почему то цены не верно сортируются (они такого вида: 1523.52, 52.5, 52.05 и т.д). И пагинация на сайте не правильно работает. PageSize указал 15, но выводит рандомно 5-6-1-2 и т.д.

Код:

$view = Yii::$app->request->get('view');
		$sort_value = (int) Yii::$app->request->get('sort_value');
		$pharm = Yii::$app->session;
		$pharm->open();
		if (isset($pharm['pid'])) {
			$pharm_id = $pharm['pid'];
			$pharms = Pharmacy::find()
			                  ->where(['pharm_id' => $pharm_id])
			                  ->limit(1)
			                  ->one();
		}
		if (!empty($pharms)) {
			$query = Product::find()
			                ->joinWith('tailing')
			                ->where(['tailings.pharm_id' => $pharm_id]);
		} else {
			$query = Product::find()->joinWith('tailing');
		}
		if (!empty($sort_value)) {
			if ($sort_value === 1) {
				$query->orderBy(['tailings.price' => SORT_ASC]);
			} elseif ($sort_value === 2) {
				$query->orderBy(['tailings.price' => SORT_DESC]);
			} elseif ($sort_value === 3) {
				$query->orderBy(['name_medication' => SORT_ASC]);
			} elseif ($sort_value === 4) {
				$query->orderBy(['name_medication' => SORT_DESC]);
			}
		}
		$pages = new Pagination([
			'totalCount' => $query->count(),
			'pageSize' => 15,
			'forcePageParam' => false,
			'pageSizeParam' => false,
		]);
		$medicines = $query->offset($pages->offset)->limit($pages->limit)->all();
		
		return $this->render('index', [
			'medicines' => $medicines,
			'pages' => $pages
		]);
  • Вопрос задан
  • 1306 просмотров
Пригласить эксперта
Ответы на вопрос 2
@yiiworld
1) вы сортируете строки, а не числа, поэтому вам кажется что сортировка не работает. Используйте для хранения цен числовые форматы данных в MySQL, например DECIMAL. Но лучше всего использовать Integer(или BigInt) и хранить в них копейки или тысячные доли копеек в зависимости от требуемой точности
2) пагинация тоже работает правильно, просто вы передаете в нее не то что подразумеваете - в totalCount вы передаете объект который подвержен мутациям. Нужно клонировать первоначальный объект от которого зависит пагинация и исполдьзовать его для count
Controller action:
public function actionIndex()
{
    $query = Article::find()->where(['status' => 1]);
    $countQuery = clone $query;
    $pages = new Pagination(['totalCount' => $countQuery->count()]);
    $models = $query->offset($pages->offset)
        ->limit($pages->limit)
        ->all();

    return $this->render('index', [
         'models' => $models,
         'pages' => $pages,
    ]);
}

View:
foreach ($models as $model) {
    // display $model here
}

// display pagination
echo LinkPager::widget([
    'pagination' => $pages,
]);
Ответ написан
HTMLord
@HTMLord Автор вопроса
COllAPSE
А насчет цен, я так понял вы имеете ввиду следующее:
если пришла цена (их мы парсим) 1000.50 то я обработав строку заношу в БД 100050. Но при выводе на сайт, последние 2 символа отсеиваю т.е 1000.50.
Тогда как быть с изначально целыми числами? Объясните дубу((

P.S

Спасибо вам! Почему меняется понял, вот только не знаю что теперь делать.

Я так понимаю что дело joinWith() и просто with(). Просто orderBy (как мне кажется) по определению не может влиять на кол-во выдачи ибо он их просто сортирует. Ошибаюсь? Пожалуйста, подскажите.

Нашел еще это:
https://github.com/yiisoft/yii2/issues/8583
https://reformatcode.com/code/php/yii2-leftjoin-no...

И такой запрос выдает 14 записей, а не 50
Product::find()
->joinWith('tailing')
->orderBy(['tailings.price' => SORT_DESC])
->limit(50)
->all();
Ответ написан
Ваш ответ на вопрос

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

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