Запросы query-buldera:
//достаем категории для главной
$categories = Category::where('display_home', 1)->get('id', 'name', 'slug');
//сюда будем схоронять посты, которые не должны повторяться
$posts_exclude = collection();
//для каждой категории
foreach ($categories as $category) {
$posts_array[$category->title] = Post:: //ищем посты,
whereHas('categories', function ($q) use ($category) { //у которых категория
$q->where('id', $category->id); // одна из найденных для главной,
})
->whereNotIn('id', $posts_exclude->pluck('id')) // и постов нет в исключаемых
->get('id', 'title', 'slug'); // только с нужными полями
$posts_exclude->merge($posts_array[$category->id]); // добавили найденные посты в коллекцию с исключаемыми
}
Затем уже выводим массив с постами (псевдокод, это надо в блейд переписать):
<ul>
foreach ($posts_array as $category => $posts) {
<li>
$category //ключ основного массива - название категории
<ul>
foreach ($posts as $post) { //значение элементов основного массива - набор постов из категории
<li>$post->title</li>
}
</ul>
</li>
}
</ul>
То есть, получаем n+1 запрос, где n - количество категорий.
Это в query-builder style. Можно, в принципе, написать один raw-запрос, но это уже за пределами топика.
Сложный одиночный query-builder запрос, полагаю, можно написать, но не вижу смысла, т.к. он будет не поддерживаемый. Да и закешить это всё можно, так что не в быстродействии дело.
p.s: Код негде проверить, писал по памяти. Надеюсь, ход мысли понятен