LaravelEloquentでクエリ結果を注文する方法

提供:Dev Guides
移動先:案内検索

このシリーズの前のパートでは、Eloquentモデル内からall()メソッドを使用してデータベースレコードを取得する方法を学習しました。 レコードを降順で並べ替えるために使用されたsortDesc()というメソッドを使用したことを思い出してください。

sortDesc()メソッドは、 Collection クラスの一部です。これは、ネイティブPHP配列の改良版として機能する強力なLaravelユーティリティクラスです。 このメソッドは、データベースクエリ自体の中で結果を並べ替える代わりに、コレクションの順序を逆にして、最後のアイテムがコレクションの最初に表示されるようにします。 これは小さな結果セットには適していますが、データベースクエリ自体で結果を並べ替えるのと同じ柔軟性はありません。

データベースクエリで結果を並べ替えるには、orderBy()メソッドを使用し、順序付けの基準として使用するテーブルフィールドを指定する必要があります。 これにより、データベースから必要な結果のみを取得するクエリをより柔軟に構築できるようになります。

次に、routes/web.phpファイルのコードを変更して、created_atテーブルフィールドに基づいて新しいものから古いものの順に結果を表示します。

テーブルの移行にtimestamps()定義を含めると、created_atフィールドとupdated_atフィールドの両方がEloquentによって管理されます。 これらのフィールドを手動で更新しないでください。ただし、これらのフィールドを使用して、クエリを並べ替えたりフィルタリングしたりできます。


コードエディタでこのファイルを開きます。

routes/web.php

コードは次のようになります。

ルート/web.php

<?php
 
use Illuminate\Support\Facades\Route;
use App\Models\Link;
use App\Models\LinkList;
 
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
 
Route::get('/', function () {
    $links = Link::all()->sortDesc();
    return view('index', [
        'links' => $links,
        'lists' => LinkList::all()
    ]);
});
 
Route::get('/{slug}', function ($slug) {
    $list = LinkList::where('slug', $slug)->first();
    if (!$list) {
        abort(404);
    }
 
    return view('index', [
        'list' => $list,
        'links' => $list->links,
        'lists' => LinkList::all()
    ]);
})->name('link-list');
 

スラッグによるリンクの一覧表示を担当する/{slug}ルートは、現在、並べ替え方法を使用していないことに注意してください。 リンクは、LinkListモデルで定義された関係を使用して、コードで強調表示されているlist変数を介して取得されます。

ここでリストに複数のリンクを追加すると、クエリはデフォルトで古いものから新しいものの順に結果を返します。 sortDesc()メソッドを使用して、$list->links呼び出し内でコレクションを並べ替えることができますが、orderBy()メソッドを使用すると、柔軟性が高まり、後で追加のフィルタリング条件を含めることができます。 このメソッドをwhere()呼び出しと連鎖させて、さらにきめ細かい結果を得ることができます。

前のコードサンプルで強調表示されている行を次の行に置き換えます。

ルート/web.php

'links' => $list->links()->orderBy('created_at', 'desc')->get(),

今回は、LinkListクラスで定義されたリレーションシップメソッドを参照する$list->links()メソッドを呼び出して、組み込みのクエリビルダーを呼び出していることに注意してください。 これは、$list->linksをクラスプロパティ(括弧なし)として呼び出すこととは異なります。これにより、モデル内のマジックメソッドが呼び出され、そのリストに関連するすべてのリンクがフェッチされます。

終了すると、完全なroutes/web.phpファイルは次のようになります。

ルート/web.php

<?php

use Illuminate\Support\Facades\Route;
use App\Models\Link;
use App\Models\LinkList;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    $links = Link::all()->sortDesc();
    return view('index', [
        'links' => $links,
        'lists' => LinkList::all()
    ]);
});

Route::get('/{slug}', function ($slug) {
    $list = LinkList::where('slug', $slug)->first();
    if (!$list) {
        abort(404);
    }

    return view('index', [
        'list' => $list,
        'links' => $list->links()->orderBy('created_at', 'desc')->get(),
        'lists' => LinkList::all()
    ]);
})->name('link-list');

ファイルを保存して閉じます。 次に、link:newArtisanコマンドを使用していくつかの新しいリンクを追加します。 デフォルトのリストを使用できます。

docker-compose exec app php artisan link:new
Output Link URL:
 > https://laravel.com/docs/8.x/eloquent

 Link Description:
 > Laravel Eloquent Docs

 Link List (leave blank to use default):
 > 

New Link:
https://laravel.com/docs/8.x/eloquent - Laravel Eloquent Docs
Listed in: default

 Is this information correct? (yes/no) [no]:
 > yes

Saved.

デフォルトのリンクリストページをリロードすると、新しいものから古いものへのリンクを取得する必要があります。

http://localhost:8000/default

同様に、リンクの説明のアルファベット順にリンクを並べ替える場合は、次のようにメソッド呼び出しでそのテーブルフィールドを使用するように行を変更する必要があります。

'links' => $list->links()->orderBy('description', 'asc')->get(),

このような変更後のリンクの順序は次のとおりです。

このシリーズの次のパートでは、LaravelEloquentクエリから合計結果数を取得する方法を学習します。