0
0

More than 1 year has passed since last update.

【Laravel】複数条件で検索する

Posted at

前提

ブログ記事に対して、「タイトル」「ペンネーム」「カテゴリ」「投稿日(期間)」の複数の条件で検索をかけたい。

流れ

①ブレードで検索フォームを作る。ボタン押下で、フォームの入力内容を同じ画面にGET送信させる。
②コントローラーの、同じブレードを表示させているメソッド(今回はindexメソッド)に、検索処理を加える。検索し加工した値をブレードに返すようにする。
③モデルに、検索処理を書く。今回は、検索ロジックを使いまわしたいので、コントローラーではなくモデルに書いた。このモデルのメソッドを、コントローラーで呼び出している。

search.blade.php
{{-- 記事検索 --}}
<div class="w-4/5 mt-10 mx-auto">
    <form class="flex flex-wrap" method="get" action="{{route('index')}}">
        <div class="flex justify-start items-center w-1/2 mt-6">
            <div class="">
                <label class="block text-gray-700 font-bold text-right mb-1 mb-0 pr-4" for="inline-full-name">
                    タイトル
                </label>
            </div>
            <div class="w-4/5">
                <input class="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white focus:border-blue-500" id="inline-full-name" type="text" name="title" placeholder="日々の記録">
            </div>
        </div>
        <div class="flex justify-end items-center w-1/2 mt-6">
            <div class="">
                <label class="block text-gray-700 font-bold text-right mb-1 mb-0 pr-4" for="inline-penname">
                    ペンネーム
                </label>
            </div>
            <div class="w-4/5">
                <input class="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white focus:border-blue-500" id="inline-penname" type="text" name="penname" placeholder="ペンタネム子">
            </div>
        </div>
        <div class="flex justify-start items-center w-1/2 mt-6">
            <div class="">
                <label class="block text-gray-700 font-bold text-right mb-1 mb-0 pr-4" for="category">
                    カテゴリ
                </label>
            </div>
            <div class="w-4/5">
                <select class="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 text-gray-700 leading-tight focus:outline-none focus:bg-white focus:border-blue-500" id="category" name="category">
                    @foreach ($categories as $category)
                    <option>{{ $category->name }}</option>
                    @endforeach
                </select>
            </div>
        </div>
        <div class="flex justify-end items-center w-1/2 mt-6">
            <div class="">
                <label class="block text-gray-700 font-bold text-right mb-1 mb-0 pr-4" for="category">
                    投稿日
                </label>
            </div>
            <div class="w-4/5 flex">
                <input class="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 mr-3 text-gray-700 leading-tight focus:outline-none focus:bg-white focus:border-blue-500" type="date" name="from" placeholder="from_date" value="">
                <span class="mx-3">~</span>
                <input class="bg-gray-200 appearance-none border-2 border-gray-200 rounded w-full py-2 px-4 ml-3 text-gray-700 leading-tight focus:outline-none focus:bg-white focus:border-blue-500" type="date" name="until" placeholder="until_date" value="">
            </div>
        </div>
        <div class="flex justify-end items-center w-1/2 mt-6">
        </div>
        <div class="flex justify-end items-center w-1/2 mt-6">
            <div>
            <button class="inline-block bg-blue-500 text-white py-2 px-4 rounded w-15 text-center shadow-md" type="submit">
                検索
            </button>
            </div>
        </div>
    </form>
</div>
ArticleController.php
// 表示
public function index(Request $request)
{
    $categories = Category::all();
    $article = new Article;
    // Articleモデルのsearchメソッドを呼び出し
    $articles = $article->search($request);
    $lastItem = $articles->lastItem();
    $total = $articles->total();
    return view('index', compact('categories', 'articles', 'lastItem', 'total'));
}
Article.php
$query = Article::query();

if ($request->has('title') && $request->title !== null) {
    $query->where('title', 'like', '%' . $request->title . '%');
}

if ($request->has('penname') && $request->penname !== null) {
    $penname = $request->penname;
    $query->with(['profile'])->whereHas('profile', function ($q) use ($penname) {
        $q->where('profiles.penname', 'like', '%' . $penname. '%');
    });
}

if ($request->has('category') && $request->category !== null) {
    $category = $request->category;
    $query->with(['category'])->whereHas('category', function ($q) use ($category) {
        $q->where('categories.name', $category);
    });
}

if ($request->has('from') && $request->from !== null) {
    $fromDate = Carbon::parse($request->from);
    $query->whereDate('created_at', '>=', $fromDate);
}

if ($request->has('until') && $request->until !== null) {
    $untilDate = Carbon::parse($request->until);
    $query->whereDate('created_at', '<=', $untilDate);
}

// 最初、withを書いていなかったら、検索ロジックが動かなかった。リレーション先のテーブルから検索する場合、withメソッドが必要。
$articles = $query->with(['profile', 'category'])->paginate(10);

return $articles;

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0