前回作った新規作成ページで、送信はできましたがデータベース処理を書いていなかったので、何も起こりませんでした。
今回はそのデータベース処理を書いていきます。
Migration
Laravelには Migration というめちゃめちゃに便利な機能が用意されています。
Migration は何かと言うと、簡単に言えばテーブルを作る機能です。
とりあえず使っていく中で覚えていきましょう。
php artisan make:migration create_todos_table
Created Migration: 2019_12_24_154568_create_todos_table
みたいな感じで表示されます。
database/migrations 配下にMigration ファイルが作成されています。
エディタでファイルを開き、次のように編集しましょう。
public function up() { Schema::create('todos', function (Blueprint $table) { $table->increments('id'); $table->string('title'); // タイトルを保存するカラム $table->string('space'); $table->date('deadline'); $table->boolean('is_complete'); $table->integer('priority'); $table->timestamps(); });
カラムの説明をします。
タイトルカラムはそのままです。todo のタイトルを保存するカラムになります。
spaceカラムは todo の場所を保存するためのカラムです。
deadline は期限です。いつまでに完了するものなのかを設定します。
この期限がすぎてしまったものに関しては、期限切れリストに追加するように後々実装していきます。
is_complete は完了したtodo をかんりするためのカラムです。
こちらは boolean (真偽値)を持たせて完了しているのか未完了なのかを判別します。
priority はその todoタスクの重要度です。
こちらは今回のアプリでは、1~5段階で重要度を設定しておき、ソート機能も実装していく予定です。
ざっとこんな感じでしょうか。
実際に実装してしまうのが一番早いと思いますので早速やってみましょう!
さて、migration ファイルの中身を説明していきます。
中身はこんな感じかと思います。
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateTodoTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('todos', function (Blueprint $table) { $table->increments('id'); $table->string('title'); // タイトルを保存するカラム $table->string('space'); $table->date('deadline'); $table->boolean('is_complete'); $table->integer('priority'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('todos'); } }
up関数とdown関数が用意されています。
up関数はmigration を実行した時に実行されるものです。
要するにmigration を実行したら先に書いたカラムたちが作成されます。
関数downには、マイグレーションの取り消しを行う為のコードを書きます。
ここでは、もしtodosというテーブルが存在すれば削除する、と書かれています。
マイグレーションファイルが用意できたので、マイグレーションを実行します。
次のコマンドを入力して下さい。
php artisan migrate
migration を実行したので up関数が実行されたはずです。
作成されたデータベースを確認してみましょう。
$mysql -u root mysql> describe todo_list.todos; ・ ・・・ここに、todosテーブルの構成が表示されます・・・ ・ mysql> exit;
ここでカラムの定義を間違えてしまうなど、何か不具合が生じた場合には ロールバック機能を使いましょう。
php artisan migrate:rollback
このコマンドを打ち込むとdown 関数が実行されて、取り消しが行われます。
ここを間違えたまま進むと、MVC での開発が進められなくなってしまいます。
ロールバック機能は大切なので覚えておきましょう!
Model を使ってみる
Laravel でデータベースを操作する時に必ず使う機能がModel です。
まずはModel の雛形を作成します。
php artisan make:model Todo
モデル名は基本的にテーブル名の単数形つまりTodo(テーブル名がtodos のため)で作成します。
このTodo モデルを使って、todos テーブルのデータを操作していきます。
Validation をかけてみる
フォームから送信されていたデータを基本的に保存していくわけですが、間違ったデータが送られてきた場合にはそのデータをそのまま保存してしまうわけにはいきません。
送られてきたデータが正しいかどうかを判断するためのものがValidation だと覚えていて下さい。
Validation はController でも設定することができますが、今回はModelに設定していきます。
Todo.php を編集します
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Todo extends Model { protected $guarded = array('id'); // 以下を追記 public static $rules = array( 'title' => 'required', 'space' => 'required', 'deadline' => 'date', 'priority' => 'digits_between:1,5', 'user_id' => 'integer', ); }
ここでは各カラムのルールの設定を行いました。
title, space は required (必ず入力が必要)
deadline は date (日付)
priority は 1 ~ 5の間の数字
という感じでルールの設定をしました。
このルールに反した値が送られてきたときは保存せずに入力フォームに送り返すようにします。
戻った先の画面では、データを登録できなかった理由を表示します。
resources/views/todo/create.blade.php をみていきます
@extends('layouts.admin') @section('title', 'todoの新規作成') @section('content') <div class="container"> <div class="row"> <div class="col-md-8 mx-auto"> <h2>todo新規作成</h2> <form action="{{ action('Admin\TodoController@create') }}" method="post" enctype="multipart/form-data"> @if (count($errors) > 0) <ul> @foreach($errors->all() as $e) <li>{{ $e }}</li> @endforeach </ul> @endif <div class="form-group row"> <label class="col-md-2" for="title">タイトル</label> <div class="col-md-10"> <input type="text" class="form-control" name="title" value="{{ old('title') }}"> </div> </div> <div class="form-group row"> <label class="col-md-2" for="space">場所</label> <div class="col-md-10"> <input type="text" class="form-control" name="space" value="{{ old('space') }}"> </div> </div> <div class="form-group row"> <label class="col-md-2" for="deadline">期限</label> <div class="col-md-10"> <input type="date" class="form-control" name="deadline" value="{{ old('deadline') }}"> </div> </div> <div class="form-group row"> <label class="col-md-2" for="priority">重要度</label> <div class="col-md-10"> <select class="form-control" name="priority" min="1" max="5" value="{{ old('priority') }}"> <?php for ($i = 1; $i <=5; $i++) { print ('<option value="' . $i. '">' . $i . '</option>'); } ?> </select> </div> </div> {{ csrf_field() }} <input type="submit" class="create-btn" value="登録"> </form> </div> </div> </div> @endsection
Validation でエラーが起こっていたら Laravel ではそのエラーを自動的に $errors に格納するようになっています。
つまりここで、$errors が空出ないときはエラーが発生しているということです。
$errors は配列になっているので、foreach でエラーメッセージを表示しています。
しかし、このままだとエラーメッセージは英語で出力されてしまいますので、ここで日本語表示に直しておきます。
config/app.php を開き、以下のように編集して下さい。
'locale' => 'ja',
続いて、表示するエラーメッセージを準備します。
英語用のファイルをコピーして、ja という名前にしておきましょう
cp -rp resources/lang/en resources/lang/ja
作成した resources/lang/ja ディレクトリにある validation.php が、バリデーションの際に使用されるカタログです。
このファイルをエディタで開き、連想配列で定義されている ‘required’ の部分を次のように書き換えて下さい。
'required' => ':attribute に入力が必要です。',
validation.php 内の ‘attributes’ に次の値を設定して下さい。これで日本語化が完了です。
'attributes' => [ 'title' => 'タイトル', 'space' => '場所', 'time' => '日時', 'deadline' => '期限', 'priority' => '優先度' ],
Controller の編集
<?php namespace App\Http\Controllers\Admin; use Illuminate\Http\Request; use App\Http\Controllers\Controller; use App\Todo; //追記 class TodoController extends Controller { public function add() { return view('admin.todo.create'); } public function create(Request $request) { // Varidationを行う $this->validate($request, Todo::$rules); $todo = new Todo; $form = $request->all(); // フォームから送信されてきた_tokenを削除する unset($form['_token']); $todo->fill($form); $todo->is_complete = 0; // データベースに保存する $todo->save(); return redirect('admin/todo/'); }
データベースの設定のところで.envファイルを編集したため、
Laravelサーバーを起動している場合は一度 サーバーを停止して再起動しましょう。
http://localhost:8000/admin/todo/create
にアクセスしてみましょう。
切り替わっただけに見えるかもしれませんが正常にデータが保存されているはずです