使用whereHas或其他类型的查询重构3个父子类别关系查询。

时间:2018-08-01 21:31:02

标签: laravel laravel-5 eloquent

因此,我具有具有以下关系的类别和渠道表。一个类别有很多频道。我想做的是获取属于父子类别的所有渠道。我目前有一种工作尝试(在控制器中尝试2),并且想知道是否可以将其放入一个查询中?

渠道类别

$table->increments('id');
$table->string('name');
$table->string('slug');
$table->integer('parent_id')->default(null);

频道

$table->increments('id');
$table->string('name');
$table->string('slug');
$table->integer('category_id');

按类别弹头路线获取所有频道

Route::get('/{channelCategory}', 'ChannelController@index');

ChannelController

public function index($channelCategory)
{

         //Attempt 1. This works perfectly fine, but would like it to be in one query if possible
        /*if($channelCategory->parent_id === 0){
            $categories = ChannelCategory::where(['parent_id' => $channelCategory->id])->pluck('id');
            $channels = Channel::whereIn('category_id', $categories)->get();
        } else {
            $channels = $channelCategory->channels;
        }*/

         //Attempt 2 whereHas Query. 
         //The problem is that it gets all posts from all parent categories instead of just one.
        /*$channels = Channel::whereHas('category', function ($query) use ($channelCategory) {
            $query->where('parent_id', $channelCategory->parent_id);
            $query->orWhere('parent_id', null);

         })->get(); */



    return view('channels.home', compact('channels'));
}

也许我想做的事在哪里没有。是否可以在一个查询中进行第二次尝试,如果可以,怎么办?

1 个答案:

答案 0 :(得分:2)

我认为您可以通过急于加载频道,然后将类别频道映射在一起来做到这一点:

$categories = ChannelCategory::with('channels')
                             ->where('parent_id', $channelCategory->id)
                             ->get();

return view('channels.home', [
    'channels' => $categories->flatMap->channels
]);

可能需要使用LengthAwarePaginator类手动进行分页:

$page = $request->get('page', 1);
$perPage = $request->get('perPage', 15);
$channels = $categories->flatMap->channels;
$items = $channels->forPage($page, $perPage);

$paginator = new LengthAwarePaginator($items, $channels->count(), $perPage, $page);

获取最新信息将涉及对集合进行排序并采取所需的限制:

$limit = $request->get('limit', 10);
$latest = collect($categories->flatMap->channels)->sortByDesc('created_at')->take($limit);