ホーム > Laravel > Laravelでカテゴリー検索を実装する方法
Laravel

Laravelでカテゴリー検索を実装する方法

いつもご利用ありがとうございます。
この記事には広告が掲載されており、その広告費によって運営しています。

関連動画

質問やフィードバック

この記事や動画に関する質問やフィードバックあれば、動画のコメント欄にてお気軽にコメントしてください。

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は、リレーション先で絞り込みをする関数です。

Laravel 11.x Eloquent:リレーション

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」を理解しておくのも大事だと思います。

シンプルにカテゴリー一覧ページがあれば良いというのであれば、パスパラメーターで実装して良いと思います。

飛んだ先で絞り込んでいくようなイメージだと最初からクエリパラメーターで作っておくと早かったりするので、将来のアップデートを見越してやるのもありだとおもいます。

ちなみに、カテゴリー一覧と検索ページの両方を作っている事業者もいます。

以上、誰かの参考になれば幸いです。

フィードバックのお願い
この記事のフィードバックがありましたらYoutubeの適当な動画にコメントしていただいたり、お問い合わせからご連絡ください。