LaravelEloquentでクエリ結果を制限してページ分割する方法
このシリーズを通して、Laravel Eloquentのいくつかの機能をテストするために、デモアプリケーションに新しいリンクを追加してきました。 アプリケーションに表示されるリンクの数に制限がないため、新しいリンクを追加するたびにメインのインデックスページが長くなることに気付いたかもしれません。 データベースエントリの数が少ない場合は問題になりませんが、長期的にはページの読み込み時間が長くなり、コンテンツの量が増えるためにレイアウトが読みにくくなる可能性があります。単一のページ。
シリーズのこのパートでは、limit()
メソッドを使用してLaravelEloquentクエリの結果の数を制限する方法と、simplePaginate()
メソッドを使用して結果をページ分割する方法を学習します。
クエリ結果の制限
開始するには、メインのアプリケーションルート(/
)を更新して、インデックスページに表示されるリンクの数を制限します。
コードエディタでWebルートファイルを開くことから始めます。
routes/web.php
次に、メインルートの定義を見つけます。
ルート/web.php
Route::get('/', function () { $links = Link::all()->sortDesc(); return view('index', [ 'links' => $links, 'lists' => LinkList::all() ]); });
強調表示された行は、Link
モデルall()
メソッドを介して現在データベースにあるすべてのリンクを取得するクエリを示しています。 このシリーズの前のパートで説明したように、このメソッドは親Model
クラスから継承され、そのモデルに関連付けられたすべてのデータベースレコードを含むコレクションを返します。 sortDesc()
メソッドは、結果のコレクションを降順でソートするために使用されます。
ここで、強調表示された行を変更して、データベースクエリの並べ替え方法orderBy()
を使用します。この方法では、[ X242X]メソッド。 クエリ結果を制限するために、limit()
メソッドへの連鎖呼び出しも含めます。 最後に、get()
メソッドを使用して、フィルタリングされた結果セットをEloquentコレクションとして取得します。
メインルートを次のコードに置き換えます。 便宜上、変更が強調表示されています。
ルート/web.php
Route::get('/', function () { $links = Link::orderBy('created_at', 'desc')->limit(4)->get(); return view('index', [ 'links' => $links, 'lists' => LinkList::all() ]); });
更新されたコードは、どのリストにあるかに関係なく、データベースに追加された最新の4つのリンクをプルします。 すべてのリンクがリストに追加されるため、訪問者は引き続き特定のリストに移動して、リンクの完全なリストを表示できます。
次に、結果をページ分けして、1つのページに一度にすべてのリンクが読み込まれない場合でも、すべてのリンクにアクセスできるようにする方法を学習します。
クエリ結果のページ付け
インデックスページは、リストされるリンクの数を制限するようになりました。これにより、ページがコンテンツで過負荷にならず、短時間でレンダリングされます。 このソリューションは多くの場合うまく機能しますが、訪問者がデフォルトでは表示されない古いリンクに引き続きアクセスできることを確認する必要があります。 これを行う最も効果的な方法は、ユーザーが結果の複数のページ間を移動できるページネーションを実装することです。
Laravel Eloquentには、データベースクエリ結果へのページ付けの実装を容易にするネイティブメソッドがあります。 paginate()
およびsimplePaginate()
メソッドは、ページネーションリンクの生成、現在要求されているページを識別するためのHTTPパラメーターの処理、および期待される値を取得するための正しい制限とオフセットを使用したデータベースのクエリを処理します。リストするページごとのレコード数に応じた結果のセット。
ここで、routes/web.php
のEloquentクエリを更新して、[X61X]previousおよびnextリンクを含む基本的なナビゲーションを生成するsimplePaginate()
メソッドを使用します。 paginate()
メソッドとは異なり、simplePaginate()
はクエリ結果の総ページ数に関する情報を表示しません。
コードエディタでroutes/web.php
ファイルを開きます。 /
ルートを更新し、limit(4)->get()
メソッド呼び出しをsimplePaginate()
メソッドに置き換えることから始めます。
ルート/web.php
... Route::get('/', function () { $links = Link::orderBy('created_at', 'desc')->simplePaginate(4); return view('index', [ 'links' => $links, 'lists' => LinkList::all() ]); }); ...
次に、同じファイルで/{slug}
ルート定義を見つけ、get()
メソッドをsimplePaginate()
メソッドに置き換えます。 完了したら、コードは次のようになります。
ルート/web.php
... 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')->simplePaginate(4), 'lists' => LinkList::all() ]); })->name('link-list'); ...
これは、完成した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::orderBy('created_at', 'desc')->simplePaginate(4); 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')->simplePaginate(4), 'lists' => LinkList::all() ]); })->name('link-list');
完了したらファイルを保存します。
これでデータベースクエリが更新されましたが、ナビゲーションバーをレンダリングするコードを含めるようにフロントエンドビューを更新する必要があります。 simplePaginate()
で取得された結果のEloquentコレクションには、links()
というメソッドが含まれています。このメソッドは、フロントエンドビューから呼び出して、ページ化されたEloquentクエリに基づいてナビゲーションセクションをレンダリングする必要なHTMLコードを出力できます。 。
また、ページ化されたEloquentコレクションのlinks()
メソッドを使用して、固有のpaginatorオブジェクトにアクセスすることもできます。これにより、現在のページなどのコンテンツに関する情報や、コンテンツの複数のページかどうか。
コードエディタでresources/views/index.blade.php
アプリケーションビューを開きます。
resources/views/index.blade.php
リンクがレンダリングされるforeach
ループを含むlinks
クラスでタグ付けされたセクションの終わりを見つけます。 そのセクションの後、そのページの最後の</div>
タグの前に次のコードを配置します。
resources / views / index.blade.php
@if ($links->links()->paginator->hasPages()) <div class="mt-4 p-4 box has-text-centered"> {{ $links->links() }} </div> @endif
このコードは、paginatorオブジェクトにアクセスし、hasPages()
メソッドを呼び出すことにより、結果の複数のページの存在をチェックします。 そのメソッドがtrueを返すと、ページは新しいdiv
要素をレンダリングし、links()
メソッドを呼び出して、関連するEloquentクエリのナビゲーションリンクを出力します。
終了すると、更新されたindex.blade.php
ページは次のようになります。
resources / views / index.blade.php
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>My Awesome Links</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/css/bulma.min.css"> <style> html { background: url("https://i.imgur.com/BWIdYTM.jpeg") no-repeat center center fixed; -webkit-background-size: cover; -moz-background-size: cover; -o-background-size: cover; background-size: cover; } div.link h3 { font-size: large; } div.link p { font-size: small; color: #718096; } </style> </head> <body> <section class="section"> <div class="container"> <h1 class="title"> @if (isset($list)) {{ $list->title }} @else Check out my awesome links @endif </h1> <p class="subtitle"> @foreach ($lists as $list)<a href="{{ route('link-list', $list->slug) }}" title="{{ $list->title }}" class="tag is-info is-light">{{ $list->title }} ({{ $list->links()->count() }})</a> @endforeach </p> <section class="links"> @foreach ($links as $link) <div class="box link"> <h3><a href="{{ $link->url }}" target="_blank" title="Visit Link: {{ $link->url }}">{{ $link->description }}</a></h3> <p>{{$link->url}}</p> <p class="mt-2"><a href="{{ route('link-list', $link->link_list->slug) }}" title="{{ $link->link_list->title }}" class="tag is-info">{{ $link->link_list->title }}</a></p> </div> @endforeach </section> @if ($links->links()->paginator->hasPages()) <div class="mt-4 p-4 box has-text-centered"> {{ $links->links() }} </div> @endif </div> </section> </body> </html>
更新が完了したら、ファイルを保存します。 ブラウザウィンドウに戻ってアプリケーションページをリロードすると、一般的なリストまたは個々のリンクリストページに4つを超えるリンクがある場合は常に、新しいナビゲーションバーが表示されます。
機能的なページネーションを設定すると、ユーザーや検索エンジンが古いアイテムにアクセスできるようにしながら、コンテンツを拡大できます。 特定の基準に基づいて一定量の結果のみが必要な場合、ページ付けが不要な場合は、limit()
メソッドを使用してクエリを簡略化し、限られた結果セットを保証できます。