Laravelでカテゴリー検索を実装する方法
いつもご利用ありがとうございます。
この記事には広告が掲載されており、その広告費によって運営しています。
関連動画
質問やフィードバック
この記事や動画に関する質問やフィードバックあれば、動画のコメント欄にてお気軽にコメントしてください。
Laravel でカテゴリー検索を実装する方法についてまとめました
カテゴリーを使って検索をする
前回、ポストにカテゴリーを選択して投稿できる、カテゴリーの機能をつけましたが、今回そのカテゴリーで検索された一覧を表示してみたいと思います。
パスパラメーターで一覧ページを作る
routes/web.php
Route::get('/category/{category}',[PostController::class,'category'])->name('category');
PostController
前回トップページで一覧の取得を書いていますが、以下のように絞り込みを追加します。
public function category($category)
{
$posts = Post::with('user')
->with('category')
//追加ここから
->whereHas('category',function($q) use($category) {
$q->where('name',$category);
})
//ここまで
->orderBy('id','desc')
->take(10)
->get();
return view('post/category',compact('posts'));
}
whereHas
は、リレーション先で絞り込みをする関数です。
resouces/views/post/category.blade.php
@foreach($posts as $post)
<div class="max-w-sm rounded mt-4 overflow-hidden shadow-lg">
<div class="px-6 py-4">
<div class="font-bold text-xl mb-2">
<a href="{{ route('post.show',['postId' => $post->id]) }}"
>{{ $post->title }}</a
>
</div>
<p>{{ $post->category->name }}</p>
<p class="text-gray-700 text-base">{{ $post->user->name }}</p>
<p class="text-gray-700 text-base">{{ $post->content }}</p>
</div>
</div>
@endforeach
これで一覧が表示できます。
localhost/category/カテゴリー1
など、自分が作ったカテゴリーにアクセスしてみてください。表示されていれば OK です。
リンクを貼る方法
カテゴリー一覧ページが出来たら、そのページに飛ぶためのリンクを作りましょう。
@foreach($posts as $post)
<a href="{{ route('category',['category' => $post->category->name]) }}"
>{{ $post->category->name }}</a
>
@endforeach
このように動的にルーティングを付けてカテゴリー一覧にリンクをつけましょう。
クエリパラメーターで実装する
routes/web.php
Route::get('/posts',[PostController::class,'search'])->name('post.search');
PostController
最初の行だけ書いてあげれば、あとはパスパラメーターとほとんど同じ書き方で実装できます。
public function search(Request $request)
{
$category = $request->category;
$posts = Post::with('user')
->with('category') //追加
->whereHas('category',function($q) use($category) {
$q->where('name',$category);
})
->orderBy('id','desc')
->take(10)
->get();
return view('post/search',compact('posts'));
}
resouces/views/post/search.blade.php
パスパラメーターと全く同じです。
@foreach($posts as $post)
<div class="max-w-sm rounded mt-4 overflow-hidden shadow-lg">
<div class="px-6 py-4">
<div class="font-bold text-xl mb-2">
<a href="{{ route('post.show',['postId' => $post->id]) }}"
>{{ $post->title }}</a
>
</div>
<p>{{ $post->category->name }}</p>
<p class="text-gray-700 text-base">{{ $post->user->name }}</p>
<p class="text-gray-700 text-base">{{ $post->content }}</p>
</div>
</div>
@endforeach
リンクを貼る
パスパラメーター用のルーティングに向けるだけで同じ書き方です。
@foreach($posts as $post)
<a href="{{ route('post.search',['category' => $post->category->name]) }}"
>{{ $post->category->name }}</a
>
@endforeach
どちらの方法がベストか
状況によると思います。
管理コストと検索に載せるためのテクニックなど色々な指標があると思いますが、自分は管理のしやすさを重視して同じコントローラーやビューを作らないというのを優先しておく方が好みです。
大前提として「データベース型 SEO」を理解しておくのも大事だと思います。
シンプルにカテゴリー一覧ページがあれば良いというのであれば、パスパラメーターで実装して良いと思います。
飛んだ先で絞り込んでいくようなイメージだと最初からクエリパラメーターで作っておくと早かったりするので、将来のアップデートを見越してやるのもありだとおもいます。
ちなみに、カテゴリー一覧と検索ページの両方を作っている事業者もいます。
以上、誰かの参考になれば幸いです。