7
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Laravel 検索機能 複数条件

Last updated at Posted at 2019-07-09

##はじめに

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の処理が走ります!

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

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

7
10
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
7
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?