実務未経験エンジニアがLaravel&ReactでWebアプリケーション開発に挑戦してみた!(その8)
0. 初めに
前回からついにバックエンド実装編開始ということで、実際に機能作成の段階に入りました。
Reactを使えるようにしたり、認証機能を実装したりするために、Breezeをインストールしましたね。
今日は、いよいよ今回作ろうとしているアプリの目玉機能のレビュー投稿機能の作成に挑戦したいと思います!
また、例によって、始め肝心ということで、基本事項の解説も結構丁寧に行います!
人によっては、少々くどいと感じるかもしれませんが、次回以降はその辺はあっさりいきますのでご了承ください。
後は、phpの基本文法の勉強はいかがでしょうか?
特にクラスとインスタンスなどはよく出てくるので、そこだけでも怪しい方は復習してみるのもいいかもしれません。
なお、今回から画面にデータを表示しますが、今のところあくまでバックエンドに重きを置いているため、見た目はテキトーです。
フロントエンド実装編までご辛抱ください。(>_<)
それでは、ごゆっくりどうぞ~!
1. 新規ブランチ作成
前回のブランチについて
例によって、新規作業ブランチを切ります。
前回の最後には、feature/02-authという名前のブランチでプッシュしました。
しかし、ファイルに変更は加えていないため、リモートのdevelopに対してプルリクエストを作成することができませんでした。
そのため、今回だけは、新規ブランチを切る前に、最初にローカルのdevelopに変更履歴をプルする必要はありません。
新規ブランチを切る
今回は、feature/03-review-crudという名前のブランチをdevelopから派生させて作業します。
実行コマンド
$ git checkout develop
(↓今回は実行しなくてOK)
$ git pull origin develop
実行コマンド
$ git checkout -b feature/03-review-crud
2. マイグレーション
さっそくレビュー投稿機能を作りたいところですが、その前にやることがあります!
そもそも、本シリーズでは何をレビューするアプリを作ろうとしていたのか覚えていますか?
そうです!研究室のレビューアプリですね!
なので、レビューするための研究室ひいてはその大学・学部を事前に作っておかないとレビュー投稿ができませんね💦
リレーションの見直し(訂正)
データベース設計は、一番最初の要件定義・設計編でER図を作成しましたね。覚えていますでしょうか?(笑)
実は、あのER図に訂正があります!
大学・学部・研究室は、複数人が編集することができ、その履歴を見られるようにしたいため、Universitesテーブル及びFacultiesテーブル、Labsテーブルは多対多のリレーションを組む必要があり、中間テーブルが必要でした。
...何を言っているのさっぱり分からねぇ...
って感じの方もいらっしゃると思います。
実は、記事を書いていく中で、僕自身も「あれ?これ中間がテーブルいるんじゃないか...??」と思い始めて今になって訂正しているくらいです。(笑)
一番最初のリレーションの説明が「多対多」とか「中間テーブル」に関する内容で難しいというのは、釈然としないため、今日のところは「そういうもんか」と思っていただいて、詳細はもうしばらく後の回に回したいと思います。
とりあえず、訂正後のこれらのテーブルのリレーションを表すと以下のような形になります。
厳密には、中間テーブルにはもう少しカラムが必要なのですが、それはこれらの作成や編集機能を実装するときにまた訂正いたします。
今日のところは、暫定的にこれでいきます
Usersテーブルのカラム修正
続いて、Usersテーブルのカラムの修正をしたいと思います。
前回は、php artisan migrateで自動的にUsersテーブルが作成されたことを確認しましたが、これはUsersテーブルを作るためのマイグレーションファイルがLaravelに最初から作られていたからでしたね。
中身を見てみましょう。ファイルパスをコピーして、「Ctrl」+「p」で張り付ければ検索できるのでしたね。
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
# ↓ここから
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();
});
# ↑ここまで
Schema::create('password_reset_tokens', function (Blueprint $table) {
$table->string('email')->primary();
$table->string('token');
$table->timestamp('created_at')->nullable();
});
Schema::create('sessions', function (Blueprint $table) {
$table->string('id')->primary();
$table->foreignId('user_id')->nullable()->index();
$table->string('ip_address', 45)->nullable();
$table->text('user_agent')->nullable();
$table->longText('payload');
$table->integer('last_activity')->index();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('users');
Schema::dropIfExists('password_reset_tokens');
Schema::dropIfExists('sessions');
}
};
public function up()の中に何やらカラムを設定する記述がされていることが分かると思います。
この中にない情報を別のファイルで作ってみたいと思います
今回は退会したユーザーの情報も保持したいので、いわゆる論理削除がされるようにします。
論理削除については以下の記事をご覧ください。
メリット・デメリットがあります。
論理削除と物理削除は何なのか?
前回、Usersテーブルのカラムはマイグレーションで作成したことを確認したのでしたね!
今日は、deleted_atのカラムを追加するためのマイグレーションファイルを作成しましょう!
マイグレーションファイルの作り方は、Laravel専用コマンドのartisanコマンドを使って作ります。phpのコンテナ内で以下のコマンドを実行します。
実行コマンド
$ php artisan make:migration add_deleted_at_to_users_table --table=users
そうすると、下のように新しいマイグレーションファイルが作成されます。
また、繰り返しになりますが、コマンドは一度実行すると取り消すのがやや面倒なので、不安な場合は、上のコマンドをコピペすることをお勧めします。
Laravelでは、以下のようにsoftDeletes()メソッドを使えば簡単に論理削除を実現できます!
up()メソッドとdown()メソッドに一行ずつ追加しましょう。
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
$table->softDeletes(); // 追加
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropSoftDeletes(); // 追加
});
}
};
up()メソッドは、マイグレーションの実行(コマンドでいうとphp artisan migrate)時に呼び出されます。
逆に、down()メソッドは、マイグレーションのロールバック(コマンドでいうとphp artisan migration:rollback)時に呼び出されます。
すなわち、直前に実行したマイグレーションを取り消すことできるということですね!
公式ドキュメントには、以下のように書かれています。
マイグレーションクラスには、upとdownの2つのメソッドを用意します。upメソッドはデータベースに新しいテーブル、カラム、またはインデックスを追加するために使用します。downメソッドでは、upメソッドによって実行する操作を逆にし、以前の状態へ戻す必要があります。
今回のup()メソッドではdeleted_atという新しいカラムを追加し、down()メソッドではそれを削除するということですね。(≧◇≦)
マイグレーションファイル内でメソッドが定義出来たら、マイグレーションを実行しましょう!
実行コマンド
$ php artisan migrate
実行出来たら、データベースの中身を見てみましょう。
Usersテーブルを開いている場合は、クルクルアイコンを押して、更新してみます。
そうすると...
確かに、deleted_atというカラムが追加されています!
前回ログインしたユーザーは、特にまだ削除操作はしていないので、null(値がない)になっていることも確認できますね!
大学・学部・研究室のテーブルを作成する
Usersテーブルの修正が終わったところで、次はレビューを投稿するための大学・学部・研究室のテーブル及びそれらとUsersテーブル間の中間テーブル(←今は深く理解しなくてOK)を作りたいと思います。
Universitiesテーブル
最初は、大学のテーブルから作成します。
例によって、マイグレーションで作ります。
まずは、Universitesテーブルを作るためのマイグレーションファイルを作ります。
テーブル名は複数形になることに注意しましょう。
実行コマンド
$ php artisan make:migration create_universities_table
では、作成されたマイグレーションファイルの中身を追加していきましょう。
図を見ながら必要なものを追加していきます。
とりあえず、大学名は必要だろうということで作りました。
また、こちらも論理削除を想定しています。
もしかしたら、「偏差値」みたいなものもあっても面白いかもしれませんが、学部とか入試方式とかによって変わってきそうで大変なので、今回はいったんやめておきます。
public function up(): void
{
Schema::create('universities', function (Blueprint $table) {
$table->id(); // 主キー
$table->string('name')->unique(); // 大学名(文字列)
$table->timestamps(); // created_at と updated_at を自動生成
$table->softDeletes(); // deleted_at カラムを追加(論理削除用
});
}
up()メソッドは、以上のようになります。
同じ大学名は作れないようにしたいと思いますので、一応unique()メソッドを使っておきました。
また、今回は新しいテーブルそのものを作ります。
down()メソッドにはテーブル自体を削除するような処理が書かれているので、特に追加するものはありません。
ちなみに、お気づきかと思いますが、ファイル名はコマンドで作成した日付や時間によって変わるので、「Ctrl」+「p」で検索したい場合は、ご自身のファイル作成コマンドの実行結果からコピペしてください。
続いて、中間テーブルの作成です。
中間テーブルは単数形で書くらしいですね。
実行コマンド
$ php artisan make:migration create_university_user_table
upメソッドを以下のように編集します(今日のところは理解まではしなくて大丈夫です)。
public function up(): void
{
Schema::create('university_user', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade'); // 追加
$table->foreignId('university_id')->constrained()->onDelete('cascade'); // 追加
$table->timestamps();
});
}
Facultiesテーブル
学部には、それが所属している大学が必ずあるはずなので、university_idが必要です。上のようなリレーション(←後で説明します)を組む必要があります。
実行コマンド
$ php artisan make:migration create_faculties_table
public function up(): void
{
Schema::create('faculties', function (Blueprint $table) {
$table->id();
$table->foreignId('university_id')->constrained()->onDelete('cascade'); // 追加
$table->string('name'); // 追加
$table->timestamps();
$table->softDeletes(); // 追加
});
}
foreignIdというのは、外部キーと呼ばれるもので、他のテーブル(今回でいうとUniversitiesテーブル)のidを指定しています。
外部キー(FK)に加えて、テーブルには自信を識別するための主キー(PK)の二種類のidがある場合があります。
※サッカーではありません!
constrained()とすることで、university_idという外部キー名から自動的にそれがUniversitiesテーブルの主キーであることを調べてくれます。
なので、名前の付け方のルールに従っているとLaravelで開発するうえでは便利だということですね。
さらに、onDelete('cascade')にすることで、紐づいている大学が削除されたときに自動的にその学部も削除されるように設定しています。
また、学部名は同じものがたくさんあるので(工学部とか)、Universitesテーブルの時のようにuniqueメソッドは使いませんでした。
また、中間テーブルも作成します。
実行コマンド
$ php artisan make:migration create_faculty_user_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.
*/
public function up(): void
{
Schema::create('faculty_user', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade'); // 追加
$table->foreignId('faculty_id')->constrained()->onDelete('cascade'); // 追加
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('faculty_user');
}
};
Labsテーブル
大学、学部ときたので、次は研究室です。
もしかしたら、大学によっては形式が異なっているところもあるかもしれませんが、おそらく多くの大学が、学部ごとに研究室が用意されている形式になっているかと思いますので、学部と研究室間でリレーションをすればよいかと思います。
そうすると、先ほど大学と学部間でリレーションを組んだので、間接的に大学と研究室を紐づけることができます。
実行コマンド
$ php artisan make:migration create_labs_table
public function up(): void
{
Schema::create('labs', function (Blueprint $table) {
$table->id();
$table->foreignId('faculty_id')->constrained()->onDelete('cascade'); // 追加
$table->string('name'); // 追加
$table->text('description')->nullable(); // 追加
$table->text('url')->nullable(); // 追加
$table->text('professor_url')->nullable(); // 追加
$table->unsignedTinyInteger('gender_ratio_male'); // 追加
$table->unsignedTinyInteger('gender_ratio_female'); // 追加
$table->timestamps();
});
}
必須ではない項目にnullableを付けました。
unsignedTinyInteger()メソッドは、 UNSIGNED TINYINTを定義できます。
詳しくは、以下をご覧ください。
・符号なし整数型
・TINYINT型
今回は、男女比の部分は負の数は入らないので符号なし整数型を採用しています。
また、Laravelのマイグレーションにどのようなメソッドが用意されているのかは、先ほどもご紹介した公式ドキュメントを見ていただくとわかります。
ただし、公式ドキュメントは分量が多いので、自分の調べたい言葉を探すときは、「Ctrl」+「F」で検索するのをお勧めいたします。
中間テーブルも作成します。
実行コマンド
$ php artisan make:migration create_lab_user_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.
*/
public function up(): void
{
Schema::create('lab_user', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade'); // 追加
$table->foreignId('lab_id')->constrained()->onDelete('cascade'); // 追加
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('lab_user');
}
};
レビューのテーブルを作成する
次に、今回投稿機能を作成するレビューのテーブルを作りたいと思います!
レビューは、「誰がレビューするのか」と「どの研究室のレビューをするのか」という情報が必要なので、UsersテーブルとLabsテーブルとそれぞれリレーションを組む必要があります。
実行コマンド
$ php artisan make:migration create_reviews_table
public function up(): void
{
Schema::create('reviews', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade'); // 外部キー
$table->foreignId('lab_id')->constrained()->onDelete('cascade'); // 外部キー
$table->unsignedTinyInteger('mentorship_style'); // 指導スタイル
$table->unsignedTinyInteger('lab_atmosphere'); // 雰囲気・文化
$table->unsignedTinyInteger('achievement_activity'); // 成果・活動
$table->unsignedTinyInteger('constraint_level'); // 拘束度
$table->unsignedTinyInteger('facility_quality'); // 設備
$table->unsignedTinyInteger('work_style'); // 働き方
$table->unsignedTinyInteger('student_balance'); // 人数バランス
$table->timestamps();
$table->unique(['user_id', 'lab_id']); // ユーザーと研究室の組み合わせは一意
});
}
最後の部分は、一人のユーザーが一つの研究室にレビューを投稿できるのは、削除しない限り1回までとするために、unique()メソッドを使っています。
これにて、今日必要なマイグレーションファイルがそろいました!
マイグレーションを実行する
マイグレーションの仕組み
そもそもなのですが、なぜマイグレーションを実行するとカラムが増えたり、テーブルが増えたりするのでしょうか?
いや、そうなるようにマイグレーションファイルに書いとるからやろっ!!
まあ、正しいです。(笑)
一応、公式ドキュメントを読んでみますと、こう書かれています。
マイグレーションはデータベースのバージョン管理のようなもので、チームがアプリケーションのデータベーススキーマを定義および共有できるようにします。ソース管理から変更を取得した後に、ローカルデータベーススキーマにカラムを手動で追加するようにチームメートに指示する必要があったことを経験していれば、データベースのマイグレーションにより解決される問題に直面していたのです。
つまり、従来の開発ではSQLのようなデータベースを直接操作できる言語を用いて、一つずつ手作業でデータベースの管理を行っていたと思いますが、マイグレーションを導入することでミスなく効率的にデータベースを設定することができるようになるのでしょう。
また、「バージョン管理」とあるように、過去にどのような変更を行ったが分かるのも便利というわけです。
「マイグレーション」の直訳が「移行」なので、一つずつポチポチ操作していた従来型のデータベース管理ではなく、前のバージョンから次のバージョンへと移り変わっていくイメージなのでしょう!(←あくまでも推測です)
試しに、これまでにどのマイグレーションが実行されているかを確認してみましょう!
実行コマンド
$ php artisan migrate:status
実行結果
どうやら、Ranが実行済みのマイグレーションファイルで、Pendingが実行待ちのマイグレーションファイルのようです。
ここで気が付いたと思いますが、日付と時刻によって実行される順番がきまっているようですね。
このようにマイグレーションは、マイグレーションファイル名(日付と時刻によって順序付けされる)によって整理されていることが分かります。
※先ほどのお見せしたファイル名と若干違うと思いますが、気にしないでください。
色々やり直したりしたせいです。(笑)
マイグレーションの実行
マイグレーションを実行します。
実行コマンド
$ php artisan migrate
履歴を確認してみます。
実行コマンド
$ php artisan migrate:status
実行結果
先ほどPendingだった箇所がRanに変わっていることが分かります。
これにて、マイグレーションは完了です!
お疲れ様でした。(≧◇≦)
3. 研究室一覧表示
シーダーでテストデータを挿入する
データベースに必要なカラムが作られたので、次はシーダーというものを利用して、データを挿入していきましょう!
公式ドキュメントによりますと、以下のような説明が書かれていいます。
Laravelは、シードクラスを使用してデータベースにデータをシード(種をまく、初期値の設定)する機能を持っています。すべてのシードクラスはdatabase/seedersディレクトリに保存します。デフォルトで、DatabaseSeederクラスが定義されています。このクラスから、callメソッドを使用して他のシードクラスを実行し、シードの順序を制御できます。
種まき開始!!
大学テーブルのシーダーファイル作成
シーディングは、シーダーファイルを作成して実行します。
まずは、以下のコマンドでファイルを作成しましょう。
実行コマンド
$ php artisan make:seeder UniversitySeeder
VS Codeで、src/database/seedersを見ると...
UniversitySeederが作成されています!
では、ファイルを開いて見てみましょう。
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class UniversitySeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
//
}
}
Laravelのコードに慣れるためにも、これまでスルーしてきた部分も簡単に解説してみたいと思います!
記事の冒頭にも言いましたが、クラスとインスタンスというものを知っていますか?(怪しい場合は復習しておきましょう)
8行目を見てみましょう。
class UniversitySeeder extends Seeder{}
これは、クラスの継承と呼ばれるものですね!
つまり、「UniversitySeederクラスはSeederクラスを継承しますよ」という意味ですね。
そして、{}の中にSeederクラスにはないメソッドを定義することで、抽象的だったSeederクラスをUniversity用にカスタマイズできるのです!
あれ? Seederクラスなんて、作った覚えないけどな...なんで継承できるんだろう...??
この疑問についての回答ですが、おそらく察しているかもしれませんね。
そうです。Laravelに最初から用意されているからです!
extendsの後ろのSeederのところにカーソルを合わせて「F12」キーを押すと、
Seederクラスが出てきました!
このファイルは間違えて編集しないようにしましょう!!
このようにLaravelでは、Web開発に必要なクラスを事前に用意してくれているので、自分で作る必要はありません。
継承されるためのクラスは、抽象度を高くして、後から継承して使う人のことも考えて作らないといけないため、結構大変なのですが、それが最初からあるというのは非常に助かりますね。
フレームワークを使うことのメリットを少しは感じられたでしょうか?
では、このSeederクラスを継承したUniversitySeederクラス内に定義されているrun()メソッド内に種まきしたいデータを書いていきましょう!
...の前に、この中身を書くのには、モデルが必要なので、以下のコマンドであらかじめ作っておいてください💦
実行コマンド
$ php artisan make:model University
Laravelでは、シード中で複数代入が自動的に無効になっているので、設定を変えます。
よくわからない方は、公式ドキュメントを読んでみてください。多分もっとわからなくなると思いますが...w
とりあえず、以下のように追加の記述を書けば、OKということです!
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class University extends Model
{
protected $fillable = ['name']; // 追加
}
では、気を取り直して、以下がシーダーのrun()メソッドです~
<?php
namespace Database\Seeders;
use App\Models\University; // 追加
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class UniversitySeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
// 大学を適当に3つ作成
University::create([
'name' => '荒木大学',
]);
University::create([
'name' => '荒木県立大学',
]);
University::create([
'name' => '荒木市立大学',
]);
}
}
::createというのは、ファサードと呼ばれるものです。ファサードの説明をすると、本記事のボリュームがすごいことになってしまうので、今日のところは説明を割愛します。
公式ドキュメントにもありますが、ファサードの中身を詳しく知る必要はなさそうです。
とりあえず、メソッドみたいに使える便利なものと覚えておいてください。
そして、createファサードの中身を複数指定するために、連想配列で書いておきました。
[ ]で配列を作って、=>でキーと値を設定できるのでしたね!
なお、名前はテキトーです。
※注意点
ファサードを利用するためには、モデルが必要ですが、今回の場合、UniversityモデルはUniversitySeederファイル上(正確には同じ名前空間)にはありません。
したがって、コンピュータ側で「このUniversityって何?」となってエラーが発生します。
そのため、お気づきかもしれませんが、ファイルの上の方で、
use App\Models\University;
のようにuse宣言をすることで、どのUniversityなのかをコンピュータに教えてあげることができます。
これでエラーが消えます。
学部テーブルのシーダーファイル作成
同じようにして、Facultiesテーブル用のシーダーを用意します。
例によって、Facultyモデルを作成し、編集します。
紐づいている大学のidも複数代入できるようにしておきます。
実行コマンド
$ php artisan make:model Faculty
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Faculty extends Model
{
protected $fillable = [
'name',
'university_id'
];
}
次に、シーダーファイルを作って、編集します。
実行コマンド
$ php artisan make:seeder FacultySeeder
<?php
namespace Database\Seeders;
use App\Models\Faculty;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class FacultySeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
// 学部を適当に4つ作成
Faculty::create([
'university_id' => 1,
'name' => '教養学部',
]);
Faculty::create([
'university_id' => 1,
'name' => '経済学部',
]);
Faculty::create([
'university_id' => 1,
'name' => '理学部',
]);
Faculty::create([
'university_id' => 1,
'name' => '工学部',
]);
}
}
全てidが1の「荒木大学」にしました。
ちなみに、学部名は埼玉大学をモデルにしています。
研究室テーブルのシーダーファイル作成
最後に、Labsテーブル用のシーダーを作ります。
実行コマンド
$ php artisan make:model Lab
$ php artisan make:seeder LabSeeder
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Lab extends Model
{
protected $fillable = [
'name',
'faculty_id',
];
}
<?php
namespace Database\Seeders;
use App\Models\Lab;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class LabSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
// 研究室を適当に5つ作成
Lab::create([
'faculty_id' => 1,
'name' => '機械工学科 材料工学研究室',
'description' => '材料の力学的性質を調べる研究室です。',
'url' => 'https://example.com/lab1',
'professor_url' => 'https://example.com/professor1',
'gender_ratio_male' => 6,
'gender_ratio_female' => 4,
]);
Lab::create([
'faculty_id' => 1,
'name' => '情報工学科',
'description' => '情報処理技術を学ぶ研究室です。',
'url' => 'https://example.com/lab2',
'professor_url' => 'https://example.com/professor2',
'gender_ratio_male' => 5,
'gender_ratio_female' => 5,
]);
Lab::create([
'faculty_id' => 1,
'name' => '応用化学科 荒木研究室',
'description' => '化学の応用を学ぶ研究室です。',
'url' => 'https://example.com/lab3',
'professor_url' => 'https://example.com/professor3',
'gender_ratio_male' => 7,
'gender_ratio_female' => 3,
]);
Lab::create([
'faculty_id' => 1,
'name' => '情報工学科',
'description' => '情報処理技術を学ぶ研究室です。',
'url' => 'https://example.com/lab4',
'professor_url' => 'https://example.com/professor4',
'gender_ratio_male' => 5,
'gender_ratio_female' => 5,
]);
Lab::create([
'faculty_id' => 1,
'name' => '機能材料工学科 荒井研究室',
'description' => '機能性材料の研究を行う研究室です。',
'url' => 'https://example.com/lab5',
'professor_url' => 'https://example.com/professor5',
'gender_ratio_male' => 4,
'gender_ratio_female' => 6,
]);
}
}
全てのfaculty_idを1にしました(訂正: 本当はid4にするべきです。のちの回で修正しますので、今は気にしないでください)。
男女比は足して10になるようにしました。
ユーザーのファクトリファイル作成
シーダーでは、一つ一つ挿入するデータを配列で定義していましたが、もっとたくさんのレコードを楽に挿入する方法はないのでしょうか?
それが、ファクトリです!
使い方は、公式ドキュメントを読んでみてください。
実は、Laravel Breezeをインストールすると、ユーザーのファクトリはLaravelが自動で作成してくれるみたいなので、特にコマンドを実行して新しいファイルを作成する必要はありません。
以下のようなファイルがあるか確認してみましょう。
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
*/
class UserFactory extends Factory
{
/**
* The current password being used by the factory.
*/
protected static ?string $password;
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'name' => fake()->name(),
'email' => fake()->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => static::$password ??= Hash::make('password'),
'remember_token' => Str::random(10),
];
}
/**
* Indicate that the model's email address should be unverified.
*/
public function unverified(): static
{
return $this->state(fn (array $attributes) => [
'email_verified_at' => null,
]);
}
}
※万が一見つからない場合は、以下のコマンドで作りましょう。
$ php artisan make:factory UserFactory --model=User
シーディングの実行
ここまでで、準備ができましたので、種まきを実行します!
...盛り上がってきているところに水を差すようで申し訳ないのですが、これはモデルの作成を済ませてからの方がやりやすいので、今日のところは種まきはお預けとなります。
すみません。((+_+))
また、記事のボリュームが想像以上に大きくなってしまったため、本記事は前編として、続きは後編にしたいと思います。
非常に後味の悪い終わり方になってしまいましたが、後編でお待ちしております。
ありがとうございました!
参考
・論理削除と物理削除は何なのか?
・符号なし整数型
・TINYINT型
これまでの記事一覧
--- 要件定義・設計編 ---
・その1: 要件定義・設計編
--- 環境構築編 ---
・その2: 環境構築編① ~WSL, Ubuntuインストール~
・その3: 環境構築編② ~Docker Desktopインストール~
・その4: 環境構築編③ ~Dockerコンテナ立ち上げ~
・その5: 環境構築編④ ~Laravelインストール~
・その6: 環境構築編⑤ ~Gitリポジトリ接続~
--- バックエンド実装編 ---
・その7: バックエンド実装編① ~認証機能作成~