0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Laravel】検索およびフィルタリングの作り方

Posted at

はじめに

この記事はLaravelの学習過程の備忘録になります

修正点および加筆が必要な場合は随時更新します

リクエストの種類(GET/POST)

検索やフィルタリングに関するリクエストは、一般的にGETリクエストが使用されます。GETはデータの取得を目的としており、検索条件をクエリパラメータとしてURLに含めることができるためです。

しかし、検索条件が複雑であったり、大量のデータを送信する必要がある場合、あるいは機密情報を含む場合は、POSTリクエストが使われることもあります。この場合、検索条件はリクエストボディに含めて送信されます。

メソッドの解説(GETの場合)

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>リクエストの検索フォーム</title>
</head>
<body>
    <h1>顧客検索フォーム(GETリクエスト)</h1>
    <form action="http://localhost:8000/api/customers" method="GET">
        <label for="name">顧客名:</label>
        <input type="text" id="name" name="name" placeholder="名前を入力してください"><br><br>

        <label for="email">メールアドレス:</label>
        <input type="email" id="email" name="email" placeholder="メールアドレスを入力してください"><br><br>

        <button type="submit">検索</button>
    </form>
</body>
</html>

<h1>顧客検索フォーム(POSTリクエスト)</h1>
    <form action="http://localhost:8000/api/customers" method="POST">
        <label for="name">顧客名:</label>
        <input type="text" id="name" name="name" placeholder="名前を入力してください"><br><br>

        <label for="email">メールアドレス:</label>
        <input type="email" id="email" name="email" placeholder="メールアドレスを入力してください"><br><br>

        <!-- CSRFトークンを追加するための隠しフィールド -->
        <input type="hidden" name="_token" value="{{ csrf_token() }}">

        <button type="submit">検索</button>
    </form>
api.php
use App\Http\Controllers\YourController;

Route::get('/customers', [YourController::class, 'search']);
Route::post('/customers', [YourController::class, 'search']);
検索するメソッドの場合.php
public function search(Request $request)
{
    $query = $request->input('query'); // ユーザーからの検索キーワードを取得

    // 顧客名またはメールアドレスがキーワードに一致するレコードを取得
    $customers = Customer::where('name', 'LIKE', "%$query%")
                        ->orWhere('email', 'LIKE', "%$query%")
                        ->get();

    return response()->json($customers); // 結果をJSON形式で返す
}

フィルタリングの場合.php
public function search(Request $request)
{
    // リクエストから'name'と'email'のパラメータを取得
    $name = $request->input('name');
    $email = $request->input('email');

    // Customerモデルからクエリビルダのインスタンスを作成
    $query = Customer::query();

    // 名前フィルタがあれば、クエリに追加
    if ($name) {
        $query->where('name', 'LIKE', "%$name%");
    }

    // メールフィルタがあれば、クエリに追加
    if ($email) {
        $query->where('email', 'LIKE', "%$email%");
    }

    // クエリを実行して結果を取得
    $customers = $query->get();

    // 結果をJSON形式で返す
    return response()->json($customers);
}

コントローラーで使用できるワイルドカード

-- 'A'で始まる顧客名を検索
SELECT * FROM customers WHERE name LIKE 'A%';

-- 'A'で終わるメールアドレスを検索
SELECT * FROM customers WHERE email LIKE '%A';

-- 'A'を含む顧客名を検索
SELECT * FROM customers WHERE name LIKE '%A%';

-- 1文字だけの顧客名を検索
SELECT * FROM customers WHERE name LIKE 'A_';

-- 2文字の顧客名を検索
SELECT * FROM customers WHERE name LIKE '__C';

例外処理について

Laravelではtry-catchブロックを使用して例外処理を行います。tryブロック内にエラーが発生する可能性のあるコードを配置し、catchブロックでそのエラーをキャッチして処理します。

public function search(Request $request)
{
    // 入力からの顧客名とメールアドレスを取得
    $name = $request->input('name');
    $email = $request->input('email');

    // クエリビルダのインスタンスを作成
    $query = Customer::query();

    try {
        // 名前フィルタがあれば、クエリに追加
        if ($name) {
            $query->where('name', 'LIKE', "%$name%");
        }

        // メールフィルタがあれば、クエリに追加
        if ($email) {
            $query->where('email', 'LIKE', "%$email%");
        }

        // クエリを実行して結果を取得
        $customers = $query->get();

        // 結果が存在しない場合
        if ($customers->isEmpty()) {
            return response()->json(['message' => '該当する顧客が見つかりませんでした。'], 404);
        }

        // 結果をJSON形式で返す
        return response()->json($customers);

    } catch (\Exception $e) {
        // 例外が発生した場合の処理
        return response()->json(['error' => 'エラーが発生しました: ' . $e->getMessage()], 500);
    }
}

コードの補足(例外)

\Exception

PHPに最初から組み込まれている例外クラスでエラー処理に関する機能を提供します。$eという変数を用意することでクラスをインスタンス化しています。

  • getMessage()
    例外が発生した際のエラーメッセージを取得します

  • getCode()
    例外のエラーコードを取得します

  • getFile()
    例外が発生したファイル名を取得します

  • getLine()
    例外が発生した行番号を取得します

  • getTrace()
    例外発生時の実行履歴を配列として取得します

  • getTraceAsString()
    実行履歴を文字列として取得します

['error' => 'エラーが発生しました: ' . $e->getMessage()],500

配列のキー(error)に対して以下の値を代入しています
エラーが発生しました: [具体的なエラーメッセージ]
「.(ドット)」は文字列の連結のために使われています

500はステータスコードを指定しており、「内部サーバーエラー」を示しています

バリデーションについて

namespace App\Http\Controllers;

use App\Models\Customer; // Customerモデルをインポート
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class CustomerController extends Controller
{
    public function search(Request $request)
    {
        // バリデーションルールの定義
        $validator = Validator::make($request->all(), [
            'name' => 'nullable|string|max:255',  // 名前は文字列、255文字以内、nullも許可
            'email' => 'nullable|email|max:255',  // メールアドレスは有効なメール形式、255文字以内
        ]);

        // バリデーションのチェック
        if ($validator->fails()) {
            return response()->json(['errors' => $validator->errors()], 422);
        }

        // バリデーションが成功した場合、検索処理を実行
        $name = $request->input('name');
        $email = $request->input('email');

        // クエリビルダのインスタンスを作成
        $query = Customer::query();

        // 名前フィルタがあれば、クエリに追加
        if ($name) {
            $query->where('name', 'LIKE', "%$name%");
        }

        // メールフィルタがあれば、クエリに追加
        if ($email) {
            $query->where('email', 'LIKE', "%$email%");
        }

        // クエリを実行して結果を取得
        $customers = $query->get();

        // 結果が存在しない場合
        if ($customers->isEmpty()) {
            return response()->json(['message' => '該当する顧客が見つかりませんでした。'], 404);
        }

        // 結果をJSON形式で返す
        return response()->json($customers);
    }
}

コードの補足(バリデーション)

Validator::make()

Laravelにおけるバリデーションを実施するためのメソッドです
第一引数: バリデーションのデータ(リクエストから取得した入力データ)を指定します
第二引数: バリデーションルールを配列で指定します。

$request->all()

リクエストに含まれるすべての入力データを取得するメソッドです
特定のフィールドだけをバリデーションしたい場合は、
$request->only(['name', 'email'])
などを使用して、必要なフィールドだけを取得できます

fails()

バリデーションが失敗した場合、trueを返します。失敗した場合には、422ステータスコード(「バリデーションエラー」)とともにエラーメッセージを返します。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?