##はじめに
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の処理が走ります!
このように書けば、メソッド毎に処理を追うこともなくなり、条件が増えた場合の追加が楽、可読性向上などのメリットがあると思います!
改善点あればご教示お願い致します!