Laravel 検索機能 複数条件


はじめに

Laravelアプリにて、複数条件の検索機能を実装しました!

文字とカテゴリーの2つで検索出来る仕様です!

始め(修正前)はコントローラー/モデルで下記のように、条件毎でメソッドを分け記述していました。(メソッド名は気にせず)


QuestionsController.php(修正前)

class QuestionsController extends Controller

{
private $question;
private $category;

public function __construct(Question $question, Category $category)
{
$this->question = $question;
$this->category = $category;
}

public function index(Request $request)
{
//カテゴリー一覧を表示するため、カテゴリーモデルでデータを連想配列で取得するメソッド
$categoryNames = $this->category->カテゴリー名取得メソッド();

$keyword = $request->input('キーワード');
$categoryId = $request->input('カテゴリー');

if (isset($keyword) && isset($categoryId)) {
$questions = $this->question->なんちゃらメソッド1($keyword, $categoryId);
} elseif (isset($keyword)) {
$questions = $this->question->なんちゃらメソッド2($keyword);
} elseif (isset($categoryId)) {
$questions = $this->question->なんちゃらメソッド3($categoryId);
} else {
$questions = $this->question->all();
}

return view('question.index', compact(['questions', 'categoryNames']));
}
}


モデル


questiion.php(修正前)

class Question extends Model

{
public function なんちゃらメソッド1($keyword, $categoryId)
{
return $this->with(['紐づくデータ'])->where('title', 'LIKE', '%' . $keyword . '%')
->where('category_id', '=', $categoryId)
->get();
}

public function なんちゃらメソッド2($keyword)
{
return $this->with(['紐づくデータ'])->where('title', 'LIKE', '%' . $keyword . '%')->get();
}

public function なんちゃらメソッド3($categoryId)
{
return $this->with(['紐づくデータ'])->where('category_id', '=', $categoryId)->get();
}
}


今回は条件が2つなので上記の記述量で収まっていますが、検索条件が増えた場合、メソッドと条件分岐をその都度書き足す必要が出てきます。

めんどくさいですし、コントローラがファットになってしまいます。

複数条件での検索を探す中で、クロージャやorWhereなど色々出てきましたが、わからず。。

最終的に下記の記述に書き直しました!


QuestionsController.php(修正後)

class QuestionsController extends Controller

{

<--- 略 --->

public function index(Request $request)
{
$categoryNames = $this->category->カテゴリー名取得メソッド();

$questions = $this->question->なんちゃらメソッド($request);

return view('question.index', compact(['questions', 'categoryNames']));
}
}


モデル


Question.php(修正後)

class Question extends Model

{
public function なんちゃらメソッド($request)
{
$keyword = $request->input('キーワード');
$categoryId = $request->input('カテゴリー');
$query = $this->with(['紐づくデータ', '紐づくデータ']);

if (isset($keyword)) {
$query->where('title', 'LIKE', '%' . $keyword . '%');
}

if (isset($categoryId)) {
$query->where('category_id', '=', $categoryId);
}

return $query->get();
}
}


inputでの値の抽出もモデルに記述し、なるべくコントローラーのコードを減らしました!

eagerロードで紐づく値を取得したものを$query変数に代入し、条件が入力されていればその条件にあったSQLの処理が走ります!

このように書けば、メソッド毎に処理を追うこともなくなり、条件が増えた場合の追加が楽、可読性向上などのメリットがあると思います!

改善点あればご教示お願い致します!