【Laravel】フリーワード検索でやりがちなミスを回避!!

こんにちは!ドイです。

前回の記事では、AWSについて学んできました。
今回は、少し話題を変えまして、Laravelでデータ取得時にやりがちなミスを紹介したいと思います。

テーブル構成は、以下の通りとします。

それでは検索機能を実装していきたいと思います。
まずはシンプルな、フリーワード検索から始めていきます。

<?php
        // $request->input()の中身
        array: ["search" => ”company1”];
<?php

        // ユーザ名
        if ($request->filled('search')) {
            $query->where('company', $request->input('search') . '%')
                ->orWhere('name', 'LIKE', '%' .  $request->input('search') . '%');
        }

検索結果は下記の通りです。

それでは次に、フリーワード検索に、地域別の検索を追加して、地域 and フリーワードのand検索を行なっていきます。

<?php
        // $request->input()の中身
        array: ["area" => ”静岡県”, "search" => ”arms”]
<?php
        // 地域
        if ($request->filled('area')) {
            $query->where('area', $request->input('area'));
        }

        // ユーザ名
        if ($request->filled('search')) {
            $query->where('company', $request->input('search') . '%')
                ->orWhere('name', 'LIKE', '%' .  $request->input('search') . '%');
        }

検索結果は下記の通りです。

本来ならば、地域[静岡県]and 名前[arms]の検索結果が欲しいのですが、地域[静岡県]or 名前[arms]の検索結果が取れてきてしまったようです。

どのようなクエリが実行されたか確認したいので、toSql()、もしくは、デバッグバーのQueriesで発行されたクエリを確認していきたいと思います。

<?php
query->toSql();

※デバッグバーを表示したい場合は、composerでbarryvdh/laravel-debugbarをインストールした上で、.envでAPP_DEBUG=trueにすると、ページ下部に表示されます

select * from `users` where (`area` = '静岡県' and `company`= 'arms' or `name` LIKE 'arms') and `users`.`deleted_at` is null

発行されたクエリを確認すると、[area] and [company] or [name] となっています。

これを回避します。
whereメソッドにクロージャで条件を繋げていきます。

<?php
        // $request->input()の中身
        array: ["area" => ”静岡県”, "search" => ”arms”]
<?php
$query = $this->user->query();
        // 地域
        if ($request->filled('area')) {
            $query->where('area', $request->input('area'));
        }

        // ユーザ名
        if ($request->filled('search')) {
            $query->where(function ($query) use ($request) {
                $query->where('company', $request->input('name') . '%')
                    ->orWhere('name', 'LIKE', '%' .  $request->input('name') . '%');
            });
        }

先ほどと同様に、toSql() or デバッグバーで発行されたクエリを確認していきます。

select * from `users` where `area` = '静岡県' and (`name` LIKE 'arms' or `company` = 'arms') and `users`.`deleted_at` is nul

[area] and ([company] or [name])のように、フリーワード検索の部分が()で囲まれました。

検索結果は下記の通りです。

取得したいデータが取れたようです。

まとめ

今回は、データ取得時のよくやるミスを紹介しました。
初めてこのミスをした時は原因がわからず、何時間も悩んでしまったものです。
クエリビルダやEloquentは、直感的にデータを取得することができますが、一方でどのようなクエリが発行されたのか意識することなくデータが取得できてしまう点もあります。思うようなデータが取れない時は、都度toSql()やデバッグバーを用いて確認していきたいと思います。