【Laravel】簡単アプリ作製【5】 商品編集機能

Laravel

すでに実装した商品一覧画面から「編集」ボタンを押し、登録済みのデータ(カテゴリ、商品名、価格、説明文)を修正して保存する機能を実装。

1. ルーティングの設定(routes/web.php)

 編集画面を表示するルート(GET)と、実際にデータを書き換えるルート(PUT)の2つを追加します。
routes/web.php

PHP
// 追加:商品編集・更新機能のルーティング
Route::get('/products/{id}/edit', [ProductController::class, 'edit'])->name('products.edit');
Route::put('/products/{id}', [ProductController::class, 'update'])->name('products.update');

2. コントローラーの編集

 指定されたIDの商品データを取得して画面に渡す edit メソッドと、データをバリデーションして上書き保存する update メソッドを追記。
app/Http/Controllers/ProductController.php

PHP
    // 追加:商品編集画面の表示
    public function edit($id)
    {
        // 編集したい商品をIDで検索(見つからない場合は404エラー)
        $product = Product::findOrFail($id);
        
        // セレクトボックス用にすべてのカテゴリも取得
        $categories = Category::all();

        return view('products.edit', compact('product', 'categories'));
    }

    // // 追加:商品の更新処理
    public function update(Request $request, $id)
    {
        // 入力チェック(新規登録時と同じバリデーション)
        $request->validate([
            'category_id' => 'required|exists:categories,id',
            'name' => 'required|max:100',
            'description' => 'required',
            'price' => 'required|integer|min:0',
        ]);

        // 対象の商品データを取得して更新
        $product = Product::findOrFail($id);
        $product->update([
            'category_id' => $request->category_id,
            'name' => $request->name,
            'description' => $request->description,
            'price' => $request->price,
        ]);

        // 一覧画面に戻り、成功メッセージを表示
        return redirect()->route('products.index')->with('success', '商品を更新しました。');
    }

3. ビュー(画面)の作成

新規登録(create.blade.php)をベースに、現在の値を初期値として表示するフォームを作ります。

  1. resources/views/products フォルダの中に edit.blade.php を新規作成します。
  2. 以下のHTMLコードを記述して保存します。
HTML
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>商品編集</title>
</head>
<body>
    <h1>商品編集</h1>

    @if ($errors->any())
        <ul style="color: red;">
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    @endif

    <!-- 更新処理(PUTメソッド)を模倣するため、@method('PUT')が必要 -->
    <form action="{{ route('products.update', $product->id) }}" method="POST">
        @csrf
        @method('PUT')
        
        <div>
            <label for="category_id">カテゴリ:</label>
            <select name="category_id" id="category_id">
                @foreach ($categories as $category)
                    <!-- バリデーションエラー時はold、通常時は現在の商品のcategory_idを選択状態にする -->
                    <option value="{{ $category->id }}" {{ old('category_id', $product->category_id) == $category->id ? 'selected' : '' }}>
                        [{{ $category->major_category_name }}] {{ $category->name }}
                    </option>
                @endforeach
            </select>
        </div>
        <br>
        
        <div>
            <label for="name">商品名:</label>
            <input type="text" name="name" id="name" value="{{ old('name', $product->name) }}">
        </div>
        <br>
        
        <div>
            <label for="price">価格:</label>
            <input type="number" name="price" id="price" value="{{ old('price', $product->price) }}">
        </div>
        <br>
        
        <div>
            <label for="description">商品説明文:</label>
            <textarea name="description" id="description">{{ old('description', $product->description) }}</textarea>
        </div>
        <br>
        
        <button type="submit">更新する</button>
        <a href="{{ route('products.index') }}">キャンセル</a>
    </form>
</body>
</html>

💡 ここがポイント! HTMLのフォームは基本的に GETPOST しかサポートしていません。Laravelでデータの更新を意味する PUT ルートを動かすには、method="POST" とした上で、フォーム内に @method('PUT') と記述する必要があります。


4. 一覧画面に「編集」リンクを追加

 最後に、前回作成した一覧画面から編集画面へ飛べるよう、テーブルの右端に「編集」ボタン(リンク)を追加します。
resources/views/products/index.blade.php

HTML
    <table border="1">
        <thead>
            <tr>
                <th>ID</th>
                <th>商品名</th>
                <th>カテゴリ</th>
                <th>価格</th>
                <th>操作</th> <!-- ★追加 -->
            </tr>
        </thead>
        <tbody>
            @foreach ($products as $product)
                <tr>
                    <td>{{ $product->id }}</td>
                    <td>{{ $product->name }}</td>
                    <td>{{ $product->category?->name }}</td> 
                    <td>¥{{ number_format($product->price) }}</td>
                    <td>
                        <!-- ★追加:商品IDをルートに渡して編集画面へリンク -->
                        <a href="{{ route('products.edit', $product->id) }}">編集</a>
                    </td>
                </tr>
            @endforeach
        </tbody>
    </table>

5. 動作確認

1.ブラウザで商品一覧画面( http://localhost/laravel-app/public/products )を開き「編集」が表示されることを確認。

2.テーブルの右端に追加された「編集」リンクをクリックし、フォームに対象商品の現在のデータが最初から入力されていることを確認し、データを変更し更新。

3.一覧画面に戻って「商品を更新しました。」と表示され、中身が変わっていれば成功。

※この記事はAIで生成後、実際に手順通り実施して加筆、修正しています。

コメント