LaravelEloquentでクエリ結果を制限してページ分割する方法
このシリーズを通して、Laravel Eloquentのいくつかの機能をテストするために、デモアプリケーションに新しいリンクを追加してきました。 アプリケーションに表示されるリンクの数に制限がないため、新しいリンクを追加するたびにメインのインデックスページが長くなることに気付いたかもしれません。 データベースエントリの数が少ない場合は問題になりませんが、長期的にはページの読み込み時間が長くなり、コンテンツの量が増えるためにレイアウトが読みにくくなる可能性があります。単一のページ。
シリーズのこのパートでは、LaravelEloquentクエリの結果の数を制限する方法を学習します。 limit()
方法、および結果をページ付けする方法 simplePaginate()
方法。
クエリ結果の制限
開始するには、メインのアプリケーションルートを更新します(/
)インデックスページに表示されるリンクの数を制限します。
コードエディタでWebルートファイルを開くことから始めます。
routes/web.php
次に、メインルートの定義を見つけます。
Route::get('/', function () {
$links = Link::all()->sortDesc();
return view('index', [
'links' => $links,
'lists' => LinkList::all()
]);
});
強調表示された行は、データベースに現在存在するすべてのリンクを取得するクエリを示しています。 Link
モデル all()
方法。 このシリーズの前のパートで説明したように、このメソッドは親から継承されます Model
クラスであり、そのモデルに関連付けられているすべてのデータベースレコードを含むコレクションを返します。 The sortDesc()
メソッドは、結果のコレクションを降順でソートするために使用されます。
ここで、強調表示された行を変更して、データベースクエリの並べ替え方法を使用します orderBy()
、を介してEloquent Collectionとして返される行の完全なセットを単に並べ替えるのではなく、データベースレベルでクエリ結果を並べ替えます。 all()
方法。 また、への連鎖呼び出しも含まれます limit()
クエリ結果を制限するためのメソッド。 最後に、 get()
フィルタリングされた結果セットをEloquentコレクションとして取得するメソッド。
メインルートを次のコードに置き換えます。 便宜上、変更が強調表示されています。
Route::get('/', function () {
$links = Link::orderBy('created_at', 'desc')->limit(4)->get();
return view('index', [
'links' => $links,
'lists' => LinkList::all()
]);
});
更新されたコードは、どのリストにあるかに関係なく、データベースに追加された最新の4つのリンクをプルします。 すべてのリンクがリストに追加されるため、訪問者は引き続き特定のリストに移動して、リンクの完全なリストを表示できます。
次に、結果をページ分けして、1つのページに一度にすべてのリンクが読み込まれない場合でも、すべてのリンクにアクセスできるようにする方法を学習します。
クエリ結果のページ付け
インデックスページは、リストされるリンクの数を制限するようになりました。これにより、ページがコンテンツで過負荷にならず、短時間でレンダリングされます。 このソリューションは多くの場合うまく機能しますが、訪問者がデフォルトでは表示されない古いリンクに引き続きアクセスできることを確認する必要があります。 これを行う最も効果的な方法は、ユーザーが結果の複数のページ間を移動できるページネーションを実装することです。
Laravel Eloquentには、データベースクエリ結果へのページ付けの実装を容易にするネイティブメソッドがあります。 The paginate()
と simplePaginate()
メソッドは、ページ付けリンクの生成、HTTPパラメーターを処理して現在要求されているページを識別し、必要なページあたりのレコード数に応じて、期待される結果のセットを取得するために正しい制限とオフセットを使用してデータベースにクエリを実行します。リストする。
ここで、Eloquentクエリを更新します routes/web.php
を使用するには simplePaginate()
前のリンクと次のリンクを使用して基本的なナビゲーションを生成するメソッド。 とは異なり paginate()
方法、 simplePaginate()
クエリ結果の総ページ数に関する情報は表示されません。
を開きます routes/web.php
コードエディタでファイルを作成します。 を更新することから始めます /
ルート、交換 limit(4)->get()
を使用したメソッド呼び出し simplePaginate()
方法:
...
Route::get('/', function () {
$links = Link::orderBy('created_at', 'desc')->simplePaginate(4);
return view('index', [
'links' => $links,
'lists' => LinkList::all()
]);
});
...
次に、 /{slug}
同じファイル内のルート定義を置き換え、 get()
との方法 simplePaginate()
方法。 完了したら、コードは次のようになります。
...
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
終了するとファイルが表示されます。 便宜上、変更点が強調表示されています。
<?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');
完了したらファイルを保存します。
これでデータベースクエリが更新されましたが、ナビゲーションバーをレンダリングするコードを含めるようにフロントエンドビューを更新する必要があります。 結果として得られるEloquentコレクションは simplePaginate()
と呼ばれるメソッドが含まれています links()
、フロントエンドビューから呼び出すことができ、ページ付けされたEloquentクエリに基づいてナビゲーションセクションをレンダリングする必要なHTMLコードを出力します。
また、使用することができます links()
固有のpaginatorオブジェクトにアクセスするためのページ付けされたEloquentコレクションのメソッド。現在のページやコンテンツのページが複数あるかどうかなどのコンテンツに関する情報を取得するためのいくつかの便利なメソッドを提供します。
を開きます resources/views/index.blade.php
コードエディタのアプリケーションビュー:
resources/views/index.blade.php
でタグ付けされたセクションの終わりを見つけます links
クラスには、 foreach
リンクがレンダリングされるループ。 そのセクションの後、最後の前に次のコードを配置します </div>
そのページのタグ:
@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
終了すると、ページは次のようになります。
<!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()
クエリを簡素化し、限られた結果セットを保証する方法。