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

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

Спасибо Зак

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]