Lesson 9

DBとモデルの準備

Lesson 9 Chapter 1
DBの作成

Lesson9ではデータベース(DB)に関する準備を行なっていきましょう。DBが存在することでデータの登録、表示、編集、削除が可能となり消去をしない限り半永久的にデータの管理を行うことが可能です。

制約キーの一覧

以下が今回使用していく制約キーです。

主キー

主キー
$table->id()

外部キー

外部キー
$table->foreign("外部キーカラム名")->references("id")->on("親テーブル")

ユニークキー

ユニークキー
$table->string(カラム名)->unique();

NOT_NULL

NOT_NULL
$table->string(カラム名)->nullable(false);

DEFAULT

DEFAULT
$table->string(カラム名)->default("デフォルト値");

この先の項目で実際にテーブルの作成を行いながら詳細の解説を行っていきます。

usersテーブルの作成

それでは早速、ユーザーのデータを管理するusersテーブルの準備を行います。こちらは新規登録の際にユーザーのデータを作成したり、ログイン時の認証を行う際に使用するテーブルになります。

usersのmigrationファイル

Laravelではmigration(マイグレーション)ファイルを用意することで、コマンド一つでテーブルの作成を行うことが可能です。usersのmigrationファイルはLaravelインストール時にデフォルトで準備がされているので新たに作成する必要はありません、以下ファイルを確認していきます。

databases > migrations > 年_月_日_000000_create_users_table

年_月_日_000000_create_users_table
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
};

各カラムタイプについてはLesson6でご紹介しているので、必要に応じて過去の学習の振り返りを行いましょう。usersのmigrationファイルではidカラム、nameカラム、emailカラム、email_verifiedカラム、passwordカラム、created_atカラム、updated_atカラムの7カラムが作成されるよう記述が行われています。

1. $table->id()

idカラムを作成している部分で、usersテーブルの主キーになる部分です。下記の範囲内でデータの作成を行うことができ、作成されたデータへ自動的に付与される番号になります。1から順番に振られていき、重複することはない為、データの特定に主に使用されます。

BIGINT(符号付き)範囲:-9223372036854775808から9223372036854775807

BIGINT(符号なし)範囲:0から18446744073709551615。

2. $table->string('name');

nameカラムを作成している部分になります。カラムタイプにstringが指定されているので、文字列のみデータの登録が許可されたカラムになります。ユーザーの名前を管理するカラムです。

3. $table->string('email')->unique()

emailカラムを作成している部分になります。カラムタイプにstringが指定されているので、文字列のみデータの登録が許可されたカラムになります。uniqueとはDB上に重複してはいけない制約を設けている部分なので、同じメールアドレスが登録されないよう制限しています。

4. $table->timestamp('email_verified_at')->nullable()

email_verified_atカラムを作成している部分になります。カラムタイプにtimestampが指定されているので、メールの送信が行われた日時(例:2023-01-01 12:00:00)を管理するカラムです。nullableとはユーザーのデータ作成時にemail_verified_atのデータは存在しない(NULL)でも可能という許可を制約している部分になります。対してnullable(false)とした場合は、NULL不可と制約します。

5. $table->string('password')

passwordカラムを作成している部分になります。カラムタイプにstringが指定されているので、文字列のみデータの登録が許可されたカラムになります。

6. $table->rememberToken()

remember_tokenカラムを作成している部分になります。ログイン時にログイン情報を管理している部分な為、アカウントは継続してログイン状態を保てる仕組みとなっています。

7. $table->timestamps()

created_atカラムとupdated_atカラムの2カラムを作成している部分になります。カラムタイプにtimestampを指定している為、created_atにはデータの作成日時、updated_atにはデータの更新日時を管理するカラムになります。

usersのmigrationファイルは特に修正する必要はありませんので、確認のみ行いました。こちらは後ほどDBに反映していきます。

todosテーブルの作成

続いてtodosテーブルの作成を行います。todosテーブルはusersテーブルと違い、デフォルトで準備されているものではありませんので、1から作成を行っていきます。

1. todosのmigrationファイル作成

それではテーブルを作成するためにmigrationファイルを作成しましょう。コマンドでファイルの作成が行えます。

ターミナル、コマンドプロンプト
php artisan make:migration create_todos_table --table=todos

コマンドのcreate_◯◯_table --table=◯◯部分には今回作成するテーブル名を入れて実行します。以下ファイルが作成されているので確認してみましょう。

databases > migrations > 年_月_日_000000_create_todos_table

年_月_日_000000_create_todos_table
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('todos', function (Blueprint $table) {
            $table->id();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('todos');
    }
};

そして追加したいカラムの記述を行ったtodosのmigrateファイルはこちらです。

年_月_日_000000_create_todos_table
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
  /**
   * Run the migrations.
   *
   * @return void
   */
  public function up()
  {
    Schema::create('todos', function (Blueprint $table) {
      $table->id();
      $table->unsignedBigInteger("user_id")->comment("ユーザーID");
      $table->foreign("user_id")->references("id")->on("users")->onDelete("cascade");
      $table->time("todo_time")->comment("対応日時");
      $table->integer("todo_priority")->comment("優先順位");
      $table->string("todo")->comment("タスク");
      $table->boolean("completed_flag")->comment("完了フラグ");
      $table->timestamps();
    });
  }

  /**
   * Reverse the migrations.
   *
   * @return void
   */
  public function down()
  {
    Schema::dropIfExists('todos');
  }
};

それぞれのカラムについて解説していきます。

1. $table->id();

usersテーブルと同じようにidカラムの作成を行っていてtodosテーブルの主キーになります。タスクが追加されるたびに1から始まる連番が付与されていきます。

2. $table->unsignedBigInteger("user_id")

タスクを追加したユーザーが誰かを判断する為にユーザーのIDが管理されるカラムになります。例えばAさん(id = 1)、Bさん(id = 2)2名のユーザーが存在していた場合、Aさんの追加したタスクにはuser_idが1、Bさんの追加したタスクにはuser_id2が代入されます。unsignedBigIntegerにより符号なしのデータのみ登録が可能としています。

3. $table->foreign("user_id")->references("id")->on("users")->onDelete("cascade")

外部キーの制約を行っている記述になります。今回は「ユーザーがタスクを追加」するwebアプリになるので「誰がどのタスクを登録したのか」をusersテーブルとtodosテーブル、それぞれ別々のテーブルで管理されるデータを紐付ける必要があります。ユーザーが削除された場合、同時に登録しているタスクも削除を行う必要性がある為、その設定を行っています。

4. $table->time("todo_time")

こちらは時間を管理するカラムになります。タスクの実行する期限を管理する際に使用します。timeを指定することで登録されている時間を基に並び替えを行うことが可能です。

5. $table->integer("todo_priority")

こちらは優先順位を低・中・高の3種類で管理するカラムになります。実際に管理されるデータは1,2,3と整数で扱い、1=低、2=中、3=高とすることで管理が行いやすくなるメリットがあります。今回の場合はいずれも1文字なのでメリットを大きく感じられることはありませんが、例えばユーザーの権限を管理者や一般のようにデータを扱う場合に整数で管理することによって1文字で管理するメリットは大きくなります。

6. $table->string("todo")

こちらはタスクを管理するカラムになります。実際に入力したテキストが登録されます。

7. $table->boolean("completed_flag")

こちらはタスクの状態が完了か未完了かを判定するデータを管理するカラムになります。boolean型なのでtrueであれば完了、falseであれば未完了と判定し、表示の区別を行っていきます。

8. $table->timestamps()

usersテーブルでもありました、created_atとupdated_atを管理するカラムになります。データの作成日時と更新日時が登録されます。

9. ->comment("◯◯")

こちらは一つ一つのカラムにコメントを残しているのみになりますので、処理に影響はありませんが、時間が経った後に見返したり、自分以外の開発者が見たり、カラム数が多い時などに何のデータが管理されているかのコメントを残すことによって作業効率化を目指しています。

以上でusersテーブルとtodosテーブルのmigrationファイルの作成が完了しました。

.envファイルの修正

最後に今回作成するアプリケーション名とDB名の変更を行うので.envファイルの記述を変更します。

変更前

.env
APP_NAME=Laravel

// 省略

DB_DATABASE=laravel

変更後

.env
APP_NAME=Laravel_Todo

// 省略

DB_DATABASE=Laravel_Todo

修正が完了したら.envファイルの変更を反映させる為、コマンドの実行を行います。

ターミナル、コマンドプロンプト
php artisan config:cache
ターミナル、コマンドプロンプト
php artisan cache:clear

以上で.envファイルの編集は完了となります。.envファイルのDB_DATABASEを変更しておくことでコマンド実行時に任意のDBを作成することができます。

migrateの実行と確認

作成したusersテーブルとtodosテーブルを実際にDBへ反映させましょう。コマンドを実行します。

ターミナル、コマンドプロンプト
php artisan migrate

エラーもなくコマンドの実行が完了したら実際にphpMyAdminでデータベースの確認を行っていきます。phpMyAdminの開き方についてはLesson5のchapter3で紹介しているので、そちらの項目を参照してください。

まずは左サイドバーにデータベース「Laravel_Todo」が作成されていることを確認できます。

phpmyadmin画面

続いてLaravel_Todo内にusersテーブルが作成されていることを確認しましょう。又、追加したカラム等に相違がないかの確認も行っておきます。

phpmyadmin、usersテーブル

最後にtodosテーブルが作成されていることを確認しましょう。こちらも、追加したカラム等に相違がないかの確認も行っておきます。

phpmyadmin、todosテーブル

DBが作成され、その中にusersテーブルとtodosテーブルが作成されていることを確認することができました。以上でDBの作成は完了になります。

Lesson 9 Chapter 2
モデルの作成

chapter2では各モデルを準備していきましょう。モデルは主にDBに関する設定や処理などを記載しておく場所になります。Laravelではモデルを使用することで容易にDBへアクセスし操作することが可能となります。又、Laravelではモデルを必ずしもモデルを使用する必要性はありませんが、DB操作の効率向上にも繋がる為、基本的にはモデルを使用すること推奨します。

Userモデルの確認

それではUserモデルの確認を行っていきましょう。UserモデルはLaravelをインストールしたデフォルトの段階で存在しているファイルになります。

app > Models > User.php

User.php
<?php

namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
}

モデルでは以下3箇所の役割を認識しておきましょう。

1. protected $fillable

この配列にはデータの操作を行いたいカラムを記述する場所になります。usersテーブルには他にもidやtimestamp系のカラムが存在しますが、これらは処理が実行された際に自動で作成されるデータであって、修正する必要性はないに等しい為、記述されていません。対してname、email、passwordには任意の値が入り、作成後も操作する可能性があるデータとなりますので、その場合は$fillableへカラムの追加を行う必要があります。カラムの指定が行われていない場合はデータの操作が行えないので注意しましょう。

2. protected $hidden

この配列には外部に公開する必要の無いデータを記述する場所になります。デフォルトでもあるようにpasswordやremember_tokenカラムは処理の中で使用されることがあってもサービス上に表示させ使用するケースはほとんどありません。このように外部へ公開する必要性のないカラムを設定しておくことで、常にクエリから除外することが可能となります。

3. protected $casts

この配列にはキャストしたいカラムとそのデータ型を記述する場所になります。デフォルトの状態はemail_verified_atをdatetime型へキャストしており、万が一処理の中で別のデータ型にキャストされてしまった場合でも、$castsへ定義しておくことによって任意のデータ型へ自動的にキャストを行うことが可能となります。

上記の3箇所はそれぞれどのような役割を持っているのかを認識しておきましょう。

Todoモデルの作成

Todoモデルは自身で作成する必要のあるモデルなので、作成していきます。コマンドを実行しましょう。

ターミナル、コマンドプロンプト
php artisan make:model Todo

作成されたTodoモデルを確認していきます。

app > Models > Todo.php

Todo.php
<?php

namespace App\Models;

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

class Todo extends Model
{
    use HasFactory;
}

続いてUserモデルに定義されていた$fillable、$hidden、$castsの定義を行っていきましょう。又、この3つの設定において必須に近いものは$fillableのみであり、$hiddenと$castsについては必要に応じて記述を行う程度の認識で構いません。以下が追記後のTodoモデルになります。

Todo.php
<?php

namespace App\Models;

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

class Todo extends Model
{
    use HasFactory;

    protected $fillable = [
        "user_id",
        "todo_time",
        "todo_priority",
        "todo",
        "completed_flag"
    ];

    protected $hidden = [
        "updated_at"
    ];

    protected $casts = [
        "completed_flag" => "bool"
    ];
}

ユーザーの操作によってデータ操作の関連性があるカラムを$fillableに設定しています。例えばtodoカラムの追記が漏れていたりすると、何度タスクの追加処理を行ってもtodoカラムにデータが作成されません。カラムの抜けがないように注意してください。

$hiddenにはupdated_atカラムを設定しています。こちらはタスクの更新を行なった時間を管理するカラムになりますが、実際に画面上では使用することはないので、チュートリアルも兼ねて設定を行っています。

$castsにはcompleted_flagカラムをbool型へキャストするように設定を行っています。取得したデータがtrueかfalseかを基準に表示処理を行う為、別のデータ型へキャストが行なわれないよう、こちらもチュートリアルを兼ねて設定しています。

これで一旦モデルの準備が完了しました。モデルを作成したことによって今後データ操作を容易に行うことが可能となりましたので、実際の処理で使用していきます。又、処理に応じて今後はモデルに追記も行っていきます。