Laravelで0から検索機能を実装する

※本サイトはアフィリエイトリンクを掲載しています。
Laravel

こんにちは。Web系エンジニアのカズです。

今回はLaravelの検索機能の実装を0から作成します。

食べ物の在庫データを保存しているテーブルに対して検索機能を加えようと思います。

前提として、環境構築が終わっている状態の方が対象です。


 

実装の流れとしては以下です。

1.ルーティングファイルの設定

2.テーブル作成

3.モデル作成

4.Bladeファイルの作成

5.controllerの作成

必要なファイル

・web.php(ルーティングファイル)

・create_foods_table(テーブル生成に必要なmigrationファイル)

・Food.php(モデルファイル)

・index.blade.php(食べ物一覧ファイル)

・FoodController.php(データを取得、検索ロジックを記載するファイル)

 

画面イメージ(検索前)

画面イメージ(名前で検索)


 

1.ルーティングファイルの設定

web.phpに下記を記載します。

Route::get('/food/index', [FoodController::class, 'index'])->name('food.index');

 

2.テーブル作成

コマンドでmigrationファイルを作成

php artisan make:migration create_foods_table

これでcreate_foods_tableが生成されます。
そのファイルを開いて編集します。
今回は「食べ物の名前」と「種類」と「消費期限」と「在庫数」のカラムを設定します。

migrationファイルが編集出来たら、migrate実行をしてテーブル生成をします。

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateFoodsTable extends Migration
{
    /**
    * Run the migrations.
    *
    * @return void
    */
    public function up()
    {
        Schema::create('foods', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('type');
            $table->date('expiration_date');
            $table->integer('stock');
            $table->timestamps();
        });
    }
    /**
    * Reverse the migrations.
    *
    * @return void
    */
    public function down()
    {
        Schema::dropIfExists('foods');
    }
}

php artisan migrate

テーブル生成されました。



 

3.モデル作成

php artisan make:model Food

必要であれば生成されたモデルファイルを編集しますが、今回は不要です。

<?php

    namespace App\Models;
    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Database\Eloquent\Model;

    class Food extends Model
    {
        use HasFactory;
    }

 

4.Bladeファイルの作成

一覧画面のbladeファイル

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>一覧画面</title>
</head>
<body>
  <h1>一覧画面</h1>
  <form action="index" method="GET">
    @csrf
    <input type="text" name="keyword" value="{{$keyword}}" />
    <input type="button" type="submit" value="検索" />
    <table border='2'>
      <tr>
        <th>名前</th>
        <th>種類</th>
        <th>消費期限</th>
        <th>在庫数</th>
      </tr>
      @foreach($foods as $food)
        <tr>
          <td>{{$food->name}}</td>
          <td>{{$food->type}}</td>
          <td>{{$food->expiration_date}}</td>
          <td>{{$food->stock}}</td>
        </tr>
      @endforeach
    </table>
  </form>
</body>
<style>
table {
  margin-top : 30px;
  border-collapse:collapse;
  width : 70%;
}
th {
  background-color : #C0C0C0
}
td {
  text-align : right;
}
</style>
</html>

 

5.controllerの作成

コントローラーを生成

php artisan make:controller PostController

コントローラーを生成したら編集

<?php

namespace App\Http\Controllers;

use App\Models\Food;
use Illuminate\Http\Request;

class FoodController extends Controller
{
    public function index(Request $request)
    {
        if (isset($request->keyword)) {
            $foods = Food::
                where('name', $request->keyword)
                ->orWhere('type', $request->keyword)
                ->get();
            }
        else {
            $foods = Food::get();
        }

        return view('food.index', [
            'foods' => $foods,
            'keyword' => $request->keyword
        ]);
    }
}

今回はnameとtypeの完全一致検索で検索させています。

ちなみに前方一致検索や後方一致検索をしたい場合はlikeを使います。

前方一致検索

Food::where("name", "LIKE", "$request->keyword%"); 

後方一致検索

Food::where("name", "LIKE", "%$request->keyword");

部分一致検索

Food::where("name", "LIKE", "%$request->keyword%");

※このlike検索はよく使用されますが、実はデータに%が入っている場合上手く機能しない場合があります。その点については別記事で、ご紹介します。

コメント