Страница 1 из 2

Сортировка связанных по промежуточной таблице

Добавлено: 2014.07.01, 15:56
Noobie
Все привет! Только начал изучать Yii.
Ситуация такая, пишу модуль галерея изображений.
В базе есть 3 таблицы

tbl_gallery
с полями:
id, name, url

tbl_images
поля:
id, sml_img, mid_img, big_img

tbl_gallery_images
поля:
id, gallery_id, image_id, sort

В модели Gallery прописываю связь

Код: Выделить всё

public function getImages()
    {
        return $this->hasMany(\app\models\Image::className(), ['id'=>'image_id'])->viaTable('{{%gallery_images}}', ['gallery_id'=>'id']);
    }
 
И всё в принципе работает, данные есть.

Но мне нужно сделать чтобы связанные изображения сортировались по полю sort из промежуточной таблицы tbl_gallery_images.
Подскажите пожалуйста, как такую сортировку реализовать?

Re: Сортировка связанных по промежуточной таблице

Добавлено: 2014.07.01, 19:27
zelenin

Код: Выделить всё

        return $this->hasMany(\app\models\Image::className(), ['id'=>'image_id'])->viaTable('{{%gallery_images}} gallery_images', ['gallery_id'=>'id'])->orderBy('gallery_images.sort');
 
как-то так.

А может и нет - надо тестировать.

Re: Сортировка связанных по промежуточной таблице

Добавлено: 2014.07.02, 01:20
Noobie
Неа, так не получается.
Как только встала задача сортировки, сразу попробовал так:

Код: Выделить всё

public function getImages()
    {
        return $this->hasMany(\app\models\Image::className(), ['id'=>'image_id'])->viaTable('{{%gallery_images}}', ['gallery_id'=>'id'])->orderBy('{{%gallery_images}}.sort');
    } 
выдает ошибку
Database Exception – yii\db\Exception
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'tbl_gallery_images.sort' in 'order clause'
The SQL being executed was: SELECT * FROM `tbl_images` WHERE `id` IN ('1', '2', '3', '4', '5') ORDER BY `tbl_gallery_images`.sort
То есть все таки идет попытка найти это поле в таблице images

Re: Сортировка связанных по промежуточной таблице

Добавлено: 2014.07.02, 10:50
codrilla
Я бы связь оставил как есть, а выборку делал бы следующим образом

Код: Выделить всё

Gallery::find()->with([
                    'images' => function($query) {
                            $query->orderBy('sort');
                        },
                ]);
 

Re: Сортировка связанных по промежуточной таблице

Добавлено: 2014.07.02, 10:53
codrilla
А в вашем примере надо вероятно писать так:

Код: Выделить всё

public function getImages()
    {
        return $this->hasMany(\app\models\Image::className(), ['id'=>'image_id'])->viaTable('{{%gallery_images}}', ['gallery_id'=>'id'])->orderBy('sort');
    } 
 

Re: Сортировка связанных по промежуточной таблице

Добавлено: 2014.07.02, 10:54
codrilla
А, виноват, у вас сортировка в связующей таблице, а не в таблице изображений. Тогда мой вариант неверен.

Re: Сортировка связанных по промежуточной таблице

Добавлено: 2015.01.12, 10:58
prot
Я тоже ищу решение сортировки связующей таблицы.
Но из ответов так и не понял, как это сделать.

Re: Сортировка связанных по промежуточной таблице

Добавлено: 2015.01.12, 11:31
Loveorigami
так перенесите sort в tbl_images.
какую особенную функцию sort выполняет в связующей таблице? У вас одна и та же фотография будет находится в разных категориях и иметь разные значения sort?

Re: Сортировка связанных по промежуточной таблице

Добавлено: 2015.01.12, 12:02
prot
Это можно сделать.
Но тогда теряется логика в сущностях. Сущность Image - не должна ничего знать о сортировке, ее это не интересует, она отвечает только за фотографию (как минимум id и путь к файлу). А вот Gallery (Gallery_Image) - отвечает за фотографии и сортировку в каждой конкретной Галерее.

Re: Сортировка связанных по промежуточной таблице

Добавлено: 2015.01.12, 15:25
aquy
Есть еще один не менее интересный вариант, чтобы не задумываться над сложными конструкциями сортировки и фильтрации можно сделать в самой БД нужное представление, из этого представления сгенерировать модель и сеарчмодель и уже сортировать и фильтровать как будто бы это одна таблица.

Re: Сортировка связанных по промежуточной таблице

Добавлено: 2015.01.14, 17:02
Loveorigami
prot писал(а):Это можно сделать.
Но тогда теряется логика в сущностях. Сущность Image - не должна ничего знать о сортировке, ее это не интересует, она отвечает только за фотографию (как минимум id и путь к файлу). А вот Gallery (Gallery_Image) - отвечает за фотографии и сортировку в каждой конкретной Галерее.
В доках есть еще вариант связи через via(). Может подойдет.
http://www.yiiframework.com/doc-2.0/yii ... %29-detail

Re: Сортировка связанных по промежуточной таблице

Добавлено: 2015.02.03, 14:05
andreyrud
В результате нашли решение или нет?

Re: Сортировка связанных по промежуточной таблице

Добавлено: 2015.04.23, 20:36
xtz
так что так и не нашли решение?

Re: Сортировка связанных по промежуточной таблице

Добавлено: 2015.05.03, 00:06
prot
Нет пока не нашел.
Уже не помню что я сделал. Кажется применил несколько запросов, либо через Query Left Join сделал запрос.

Re: Сортировка связанных по промежуточной таблице

Добавлено: 2015.05.03, 00:31
pavlm
вот такой вариант есть:

Код: Выделить всё

$g = Gallery::find()->with(['galleryImages', 'galleryImages.image'])->one();
$imgs = ArrayHelper::getColumn($g->galleryImages, 'image');
 

Re: Сортировка связанных по промежуточной таблице

Добавлено: 2015.05.03, 04:43
Noobie
Я задачу решил, но как именно реализовал сейчас не вспомню. Поищу у себя исходники того проекта, где это реализовывал, выложу.
Точно помню что без join'ов у меня было, но само решение как по мне, являлось костылем.

Re: Сортировка связанных по промежуточной таблице

Добавлено: 2015.05.03, 05:35
Noobie
Вот так я реализовал это тогда, в модель Gallery добавил метод getImages, код:

Код: Выделить всё

    public function getImages()
    {
        if($this->isNewRecord) return false;

        // получаем id изображений, отсортированных по полю 'sort' и формируем условие IN        
        $image_ids = GalleryImage::find()->select('image_id')->asArray()->where('gallery_id='.$this->id)->orderBy('sort')->all();
        $in = '';
        foreach($image_ids as $item){
            $in .= $item['image_id'] .', ';
        }
        $in = trim( trim($in), ', ' );

        $query = new \Yii\db\Query();
        $query->from('{{%images}}');
        $query->where("id IN ($in)");
        $query->orderBy("FIELD (id, $in)");
        $sql = str_replace('`', '', $query->createCommand()->sql);
        $models = \app\modules\gallery\models\Image::findBySql($sql)->all();
        return $models;
    }

Re: Сортировка связанных по промежуточной таблице

Добавлено: 2015.09.16, 09:56
Tpona
Где-то нашел вот такой код, но он не работает:

Код: Выделить всё

public function getSavedQuestions()
    {
        return $this->hasMany(Question::className(), ['id' => 'questionId'])
            ->viaTable('{{%interview_question}}', ['interviewId' => 'id'], function($query){
                return $query->orderBy(['{{%interview_question}}.sort' => SORT_ASC]);
            })->where(['saved' => 1]);
    }
Кто-то нашел решение, как сделать именно связь а не выборку путем построения запроса?

Re: Сортировка связанных по промежуточной таблице

Добавлено: 2015.09.16, 10:08
Tpona
Впринципе, как то так можно сделать все работает

Код: Выделить всё

        return Question::find()
            ->select('{{%question}}.*')
            ->innerJoin( '{{%interview_question}}', '{{%interview_question}}.questionId={{%question}}.id' )
            ->where('{{%question}}.saved=1')
            ->orderBy(['{{%interview_question}}.sort' => SORT_ASC])
            ->all();

Re: Сортировка связанных по промежуточной таблице

Добавлено: 2015.09.16, 10:22
zelenin
спросил про связь, а не запрос, ответил сам себе запросом - все работает. ок