Laravel 多层groupBy

Laravel Multilayered groupBy

假设我们有这条记录:

---------------------------------------------------------
|   id  |   relation_id |   color       |   text        |
---------------------------------------------------------
|   1   |       1       |   /* null */  |   text_001    |
---------------------------------------------------------
|   2   |       1       |   /* null */  |   text_002    |
---------------------------------------------------------
|   3   |       2       |   /* null */  |   text_003    |
---------------------------------------------------------
|   4   |       2       |   /* null */  |   text_004    |
---------------------------------------------------------
|   5   |       3       |   /* null */  |   text_005    |
---------------------------------------------------------
|   6   |       3       |   /* null */  |   text_006    |
---------------------------------------------------------
|   7   |       4       |       red     |   text_007    |
---------------------------------------------------------
|   8   |       4       |       red     |   text_008    |
---------------------------------------------------------
|   9   |       4       |       green   |   text_009    |
---------------------------------------------------------
|   10  |       4       |       green   |   text_010    |
---------------------------------------------------------
|   11  |       4       |       blue    |   text_011    |
---------------------------------------------------------
|   12  |       4       |       blue    |   text_012    |
---------------------------------------------------------

虽然假设我们在 DummyController 中有此代码:

// take note, groupBy() is using a relation here
public function index(Dummy $dummy)
{
    $dummyRecord = $dummy->with('anotherModel')->get()->sortBy('relation_id')->groupBy('anotherModel.column_name');
    return view('index')->with('dummyRecord', $dummyRecord);
}

最后,假设我们的 index.blade 中有 @foreach ($dummyRecord as $dummy_column_name => $dummy),我们可以这样显示结果:

// assume this is a div
---------------------
|   relation 1      |
---------------------
|       text_001    |
|       text_002    |
---------------------

// assume this is a div
---------------------
|   relation 2      |
---------------------
|       text_003    |
|       text_004    |
---------------------

// assume this is a div
---------------------
|   relation 3      |
---------------------
|       text_005    |
|       text_006    |
---------------------

// assume this is a div
---------------------
|   relation 4      |
---------------------
|       text_007    |
|       text_008    |
|       text_009    |
|       text_010    |
|       text_011    |
|       text_012    |
---------------------

但我想将 relation 4color 记录显示为 div 内的 div,这使得最终输出在index.blade 文件:

// assume this is a div
---------------------
|   relation 1      |
---------------------
|       text_001    |
|       text_002    |
---------------------

// assume this is a div
---------------------
|   relation 2      |
---------------------
|       text_003    |
|       text_004    |
---------------------

// assume this is a div
---------------------
|   relation 3      |
---------------------
|       text_005    |
|       text_006    |
---------------------

// assume this is a div
---------------------------------------------
|   relation 4                              |
---------------------------------------------
|                                           |
|   // assume this is a div inside a div    |
|   -----------------                       |
|   |   red         |                       |
|   -----------------                       |
|   |   text_007    |                       |
|   |   text_008    |                       |
|   -----------------                       |
|                                           |
|   // assume this is a div inside a div    |
|   -----------------                       |
|   |   green       |                       |
|   -----------------                       |
|   |   text_009    |                       |
|   |   text_010    |                       |
|   -----------------                       |
|                                           |
|   // assume this is a div inside a div    |
|   -----------------                       |
|   |   blue        |                       |
|   -----------------                       |
|   |   text_011    |                       |
|   |   text_012    |                       |
|   -----------------                       |
|                                           |
---------------------------------------------

我应该使用另一个 groupBy 来对颜色记录进行排序,还是可以在 index.blade 文件中添加另一个排序代码?

可以使用集合[map()][1]来解决目的。

$dummy->with('anotherModel')
    ->get()
    ->sortBy('relation_id')
    ->groupBy('relation_id', true)
    ->map(function($q){
        // group by color
        return collect($q)->groupBy('color', true);
    })
    ->all();


  [1]: https://laravel.com/docs/8.x/collections#method-map

你可以group by multiple nested properties这样:

$dummy
    ->with('anotherModel')
    ->get()
    ->sortBy('relation_id')
    ->groupBy(['anotherModel.column_name', 'anotherModel.anotherColumn_name']);

然后在你的 blade 中循环它:

@foreach(/* ... */)
    <div>
        relation {{ $i }}
        @foreach(/* ... */)
            <div>
                {{ $color }}
                @foreach(/* ... */)
                   {{ $text}}
                @endforeach
            </div>
        @endforeach
    </div>
@endforeach