この記事のゴール
- 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');
![](https://macocci7.net/blog/wp-content/uploads/2023/05/form01.png)
ブラウザで動作確認
ブラウザのアドレスバーに http://localhost/todo を入力してアクセスします。
![](https://macocci7.net/blog/wp-content/uploads/2023/05/form02.png)
「新規登録」のリンクが表示されているのでクリックします。
「やること」の内容を入力して「登録」ボタンをクリックします。
![](https://macocci7.net/blog/wp-content/uploads/2023/05/form03.png)
入力した内容が一覧に表示されています。この一覧はDBから全件取得しているので、
DBに登録されていることが確認できます。
![](https://macocci7.net/blog/wp-content/uploads/2023/05/form04.png)
動作確認として、「新規登録」フォームで何も入力せずに「登録」ボタンを
クリックしたときの挙動も確認しておきましょう。
一覧ページにリダイレクトせずに、「新規登録」フォームページに戻されます。
一覧ページに戻っても一覧は以前のままです。
エラーメッセージについては次回を予定しています。
今回はここまでです。お疲れさまでした。
コメント