前提
ブログ記事に対して、「タイトル」「ペンネーム」「カテゴリ」「投稿日(期間)」の複数の条件で検索をかけたい。
流れ
①ブレードで検索フォームを作る。ボタン押下で、フォームの入力内容を同じ画面に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;