Laravel - Как разбить объединенную коллекцию Many To Many (Polymorphi c)? - PullRequest
0 голосов
/ 17 марта 2020

Попытка выяснить, как получить две связанные модели (очевидно, объединенные) моих отношений «Много ко многим» («Полиморф» c).

Что у нас есть:

  • 3 модели: Bucket, Template и DesignPack.
  • Bucket имеет «многие ко многим» (Polymorphi *) 1035 *) отношения с Template и DesignPack (это означает, что у нас есть сводные таблицы сводной таблицы). По сути, Bucket может иметь (быть связанным с) как Template, так и DesignPack.
  • Laravel 6. *

Что я хочу получить:

  • Я хочу, чтобы шаблоны и пакеты Bucket были объединены в одну коллекцию и разбиты на страницы!

Пожалуйста, проверьте одно из решений, которые я пробовал:

$templates = Bucket::find($bucket_id)->templates()->select(['id', 'file_name as name', 'size', 'preview']);        
$design_packs = Bucket::find($bucket_id)->dps()->select(['id', 'name', 'size', 'preview']);

$all = $templates ->union($design_packs )->paginate(10);

К сожалению, это решение выдает мне ошибку (хотя я проверил, что возвращает каждый запрос, и он возвращает те же поля, а не разные):

"SQLSTATE[21000]: Cardinality violation: 1222 The used SELECT statements have a different number of columns (SQL: (select `id`, `size`, `preview`, `bucketables`.`bucket_id` as `pivot_bucket_id`, `bucketables`.`bucketable_id` as `pivot_bucketable_id`, `bucketables`.`bucketable_type` as `pivot_bucketable_type` from `design_packs` inner join `bucketables` on `design_packs`.`id` = `bucketables`.`bucketable_id` where `bucketables`.`bucket_id` = 3 and `bucketables`.`bucketable_type` = App\DesignPack and `design_packs`.`deleted_at` is null) union (select `id`, `size`, `preview` from `templates` inner join `bucketables` on `templates`.`id` = `bucketables`.`bucketable_id` where `bucketables`.`bucket_id` = 3 and `bucketables`.`bucketable_type` = App\Template and `templates`.`deleted_at` is null))"

Есть ли другой способ получить то, что я хочу? Может быть примеры, ссылки на документацию или какие-нибудь полезные идеи?

Буду так благодарен ребятам за любую помощь! Спасибо!

1 Ответ

1 голос
/ 17 марта 2020

Вы можете передать замыкание запросам:

$templates = Bucket::whereHas('templates', function($query) use $bucket_id {
       $query->where('bucket_id', $bucket_id);
    })->get();

$designPacks = Bucket::whereHas('dps', function($query) use $bucket_id {
       $query->where('bucket_id', $bucket_id);
    })->get();

, а затем объединить 2 красноречивые коллекции:

$mergedCollections = $templates->merge($designPacks);

теперь у вас есть коллекция обоих результатов, вы можете выбрать определенную c поля, ограничить результаты или др c. вы можете захотеть взглянуть на Laravel помощников по сбору.

также, если вы настаиваете на использовании объединения, вы можете взглянуть на это обращение: Используемые операторы SELECT имеют другое число столбцов (REDUX !!)

...