Laravel でフォームからのデータをレコード挿入

Laravel

この記事のゴール

  • Laravel でフォームからのデータを取得しデータベースにレコード挿入する。

前提条件

  • Larabel でデータベースからのレコード取得はできている。

 ※レコードの挿入ができているかどうかの確認の為に必要です。

 ※まだの場合は、前回の記事を参考にしてください。

これからやる作業

  • Bladeテンプレート編集(フォームへのリンク設置)
  • Bladeテンプレートでフォーム作成
  • モデル編集(バリデーション設定)
  • コントローラーのメソッド作成
  • ルーティング
  • ブラウザで動作確認

Bladeテンプレート編集(フォームへのリンク設置)

[resources/views/todo/index.blade.php] を開いて次のように編集して保存します。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>{{$pageTitle}}</title>
    </head>
    <body>
        <h1>{{$pageTitle}}</h1>
        <a href="{{route('todo.create')}}">新規登録</a><br />
        @isset($todos)
        @foreach($todos as $todo)
        <p>
            {{$todo->id}}:{{$todo->todo}} {{$todo->done ? '[完了]' : ''}}
             <a href="{{route('todo.detail', ['id' => $todo->id])}}">→</a>
        </p>
        @endforeach
        @else
        <p>todoは登録されていません。</p>
        @endisset
    </body>
</html>

9行目にフォームへのリンクを設置しています。

Bladeテンプレートでフォーム作成

todoを新規作成するための入力フォームをつくっていきます。

フォルダ [resouces/views/todo/] の中に、新しいファイル [create.blade.php] を作成します。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>{{$pageTitle}}</title>
    </head>
    <body>
        <h1>{{$pageTitle}}</h1>
        <form method="POST" action="{{route('todo.store')}}">
            @csrf
            <label>やること:</label>
            <input type="text" name="todo" size="40" maxlength="255" />
            <input type="hidden" name="done" value="0" />
            <button type="submit" name="submit" id="submit">登録</button>
        </form>
    </body>
</html>

10行目はCSRF対策のトークンを埋め込むBladeの関数です。

<input type="hidden" name="_token" value="5QpmzjwgibiLl6tgAqyUAhUgL9fwIAvt7nm743Oz">

あとで実際にブラウザで表示すると、上のような input タグが埋め込みされます。

モデル編集(バリデーション設定)

フォームからの入力値は、有効な値かどうかをチェックする必要があります。

この有効性のチェックをバリデーションといいます。

Laravel では、モデルクラスにバリデーションの設定を記述します。

モデルクラスファイル [app\Models\Todo.php] を次のように編集し保存します。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Todo extends Model
{
    public static $rules = [
        'todo' => 'required|string|max:255',
        'done' => 'required|in:0,1',
    ];

    protected $fillable = [
        'todo',
        'done',
    ];

    use HasFactory;
}

10行目~13行目に追記しているのが、バリデーション設定です。

$rules = []; 中に、カラム名をキーとしてバリデーションルールを指定します。

  • require ・・・ 必須。
  • string ・・・ 文字列かどうか。
  • max:255 ・・・ 文字列の場合は文字数が255文字以内かどうか。数の場合は最大値。
  • in:0,1 ・・・ 0か1のいずれかであるか。リストをカンマ区切りで指定します。

バリデーションルールは他にも色々あります。公式ドキュメントを参考にしてください。

15行目~18行目で追記しているのが、レコード挿入・更新時に、フォームの入力値のうちで

適用できる項目名です。これで余計な値の混入を防ぎます。

コントローラーのメソッド作成

フォルダ [app\Http\Controllers\TodoController.php] を編集して保存します。

<?php

namespace App\Http\Controllers;

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

class TodoController extends Controller
{
    public function index()
    {
        return view('todo.index', [
            'pageTitle' => 'TODOリスト',
            'todos' => Todo::all(),
        ]);
    }

    public function retrieve($id)
    {
        return view('todo.detail', [
            'pageTitle' => 'TODO詳細',
            'todo' => Todo::find($id),
        ]);
    }

    public function create()
    {
        return view('todo.create', [
            'pageTitle' => 'TODO新規登録',
        ]);
    }

    public function store(Request $request)
    {
        $this->validate($request, Todo::$rules);
        $todo = new Todo();
        $todo->fill($request->except('_token'))->save();
        return redirect(route('todo.index'));
    }
}

26行目~39行目を追記しています。

メソッド create() は入力フォーム表示、

メソッド store() でフォームの入力受取、バリデーション、レコード挿入をしてから

todo 一覧ページへリダイレクトを行うようにしています。

多重登録を防ぐ目的でリダイレクトを行います。

35行目の validate() メソッドでバリデーションエラーが出ると、

フォームページへ戻されます。

ルーティング

[routes\web.php] を編集します。次の2行を追記して保存します。

    Route::get('/create', [TodoController::class, 'create'])->name('create');
    Route::post('/store', [TodoController::class, 'store'])->name('store');

ブラウザで動作確認

ブラウザのアドレスバーに http://localhost/todo を入力してアクセスします。

「新規登録」のリンクが表示されているのでクリックします。

「やること」の内容を入力して「登録」ボタンをクリックします。

入力した内容が一覧に表示されています。この一覧はDBから全件取得しているので、

DBに登録されていることが確認できます。

動作確認として、「新規登録」フォームで何も入力せずに「登録」ボタンを

クリックしたときの挙動も確認しておきましょう。

一覧ページにリダイレクトせずに、「新規登録」フォームページに戻されます。

一覧ページに戻っても一覧は以前のままです。

エラーメッセージについては次回を予定しています。

今回はここまでです。お疲れさまでした。

コメント

タイトルとURLをコピーしました