Laravel 5.1 Eloquent Query Builder Разбиение на страницы с помощью Raw SQL

Я пытаюсь решить проблему с Laravel 5.1 Eloquent Query Builder, где разбиение на страницы нарушает SQL, когда Query Builder содержит RAW Selects.

Фон

Я создаю веб-приложение, где пользователь может запросить список профилей. Внешний интерфейс имеет пользовательский интерфейс фильтрации. Пользовательский интерфейс фильтрации имеет параметр "содержит 1 или более изображений" и "содержит 1 или более видео".

База данных MySQL содержит таблицу для профилей и отдельную таблицу для элементов мультимедиа (изображений, видео и т. Д.). В таблице "Медиа" есть столбец "Идентификатор профиля" (владелец) и колонка типа медиа (представляющая изображение, видео и т. Д.).

Поэтому я пытаюсь подсчитать количество элементов мультимедиа, которые соответствуют идентификатору профиля, а затем оценить, если количество> 1.

Есть также другие параметры фильтрации, которые являются простыми операторами WHERE в таблице профиля (однако они работают нормально) - например. пол, доб и т.д.

Я добавил следующий метод в мою модель профиля laravel:

public function scopeMediaCounts($query, $media_type, $count = null, $operator = '=') 
{
    $media_types = array();

    switch ($media_type) {
        case 'images':
            $media_types[] = 1;
            break;
        case 'videos':
            $media_types[] = 2;
            $media_types[] = 3;
            break;
    }

    // $query to build

}

Я намерен использовать это так: ->mediaCounts('images', 1, '>')->mediaCounts('videos', 1, '>')


Что я пробовал

Я пробовал различные комбинации, основанные на документации laravel, ответах переполнения стека, поиске в Google и методе проб и ошибок. Однако самое близкое, что я могу получить ниже:

public function scopeMediaCounts($query, $media_type, $count = null, $operator = '=') 
{
    $media_types = array();

    switch ($media_type) {
        case 'images':
            $media_types[] = 1;
            break;
        case 'videos':
            $media_types[] = 2;
            $media_types[] = 3;
            break;
    }

    $types = implode(',', $media_types);
    $query->leftJoin('media', 'profiles.profile_id', '=', 'media.profile_id')
        ->selectRaw("profiles.*, count(media.profile_id) as {$media_type}Count")
          ->whereIn('media.type', $media_types)
      ->groupBy('profiles.profile_id');

    if (is_int($count))
        $query->having("{$media_type}Count", $operator, $count);

    return $query;
}

Код выше ломается, когда есть попытка использовать ->mediaCounts() используется более одного раза.

Упс, похоже, что-то пошло не так.

2/2
QueryException in Connection.php line 662:
SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 'media' (SQL: select profiles.*, count(media.profile_id) as imagesCount, profiles.*, count(media.profile_id) as videosCount from `profiles` left join `media` on `profiles`.`profile_id` = `media`.`profile_id` left join `media` on `profiles`.`profile_id` = `media`.`profile_id` where `media`.`type` in (1) and `media`.`type` in (2, 3) group by `profiles`.`profile_id`, `profiles`.`profile_id` having `imagesCount` >= 1 and `videosCount` >= 1)

public function scopeMediaCounts($query, $media_type, $count = null, $operator = '=') 
{
    $media_types = array();

    switch ($media_type) {
        case 'images':
            $media_types[] = 1;
            break;
        case 'videos':
            $media_types[] = 2;
            $media_types[] = 3;
            break;
    }

    $types = implode(',', $media_types);

    $query
        ->selectRaw("{$this->table}.*, ( SELECT  COUNT(*)
            FROM    ver3_data_media           media
            WHERE   media.profile_id      = {$this->table}.profile_id
            )   AS      \"{$media_type}Count\"")
        ->having("{$media_type}Count", $operator, $count);

    return $query;
}

В приведенном выше примере не учитываются типы мультимедиа, но он работает до тех пор, пока не будет передан в функцию paginate.

Ошибка: ->mediaCounts('images', 1, '>')->mediaCounts('videos', 1, '>')->paginate(20)

QueryException in Connection.php line 662:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'imagesCount' in 'having clause' (SQL: select count(*) as aggregate from `profiles` having `imagesCount` >= 1 and `videosCount` >= 1)

Однако, если я дам дамп SQL до того, как он попадет на Paginate, SQL-запрос прекрасно работает в MySQL Workbench (за исключением того, что он не выбирает типы носителей):

select profiles.*, ( SELECT  COUNT(*)
            FROM    media           media
            WHERE   media.profile_id      = profiles.profile_id
    )       AS      imagesCount, profiles.*, ( SELECT  COUNT(*)
            FROM    media           media
            WHERE   media.profile_id      = profiles.profile_id
    )       AS      videosCount from `profiles` group by `profiles`.`profile_id`, `profiles`.`profile_id` having `imagesCount` >= 1 and `videosCount` >= 1

На самом деле не уверен, как решить проблему Paginate. Другие вопросы переполнения стека инструктируют вручную создавать нумерацию страниц, однако примеры были на уровне 4, с использованием методов, которые, кажется, не существуют в 5.1

Пожалуйста помоги.

Спасибо Зак

0 ответов

Другие вопросы по тегам