ある「学生」が履修できる「講義」は多数あり,ある「講義」を履修する「学生」も多数いることから,「学生」と「講義」の関係は「多対多」になります.
その後のセクションでは,学生の履修登録を変更する方法などを説明します.また,学生の情報を削除したときに連鎖的に履修の情報を削除したり,ある講義の情報を削除したときに学生の履修情報を連鎖的に変更する方法も説明します.
学生と講義の情報を格納するテーブル students と lectures を作成します.なお,テーブル名は先頭小文字の複数形を用いることに注意してください.
vagrant@ubuntu2204 laravelRelationship $ pwd ⏎ /home/vagrant/Documents/laravel/laravelRelationship vagrant@ubuntu2204 laravelRelationship $ php artisan make:migration create_students_table --create=students ⏎ INFO Migration [database/migrations/2023_10_17_162040_create_students_table.php] created successfully. vagrant@ubuntu2204 laravelRelationship $ php artisan make:migration create_lectures_table --create=lectures ⏎ INFO Migration [database/migrations/2023_10_17_162102_create_lectures_table.php] created successfully. vagrant@ubuntu2204 laravelRelationship $
マイグレーションファイルの雛形が生成されたので,students テーブルを生成するためのマイグレーションファイル yyyy_mm_dd_hhmmss_create_students_table を編集します.
database/migrations/2023_10_17_162040_create_students_table.php
public function up(): void
{
Schema::create('students', function (Blueprint $table) {
$table->id();
$table->string('name', 100);
$table->timestamps();
});
}
database/migrations/2023_10_17_162102_create_lectures_table.php
public function up(): void
{
Schema::create('lectures', function (Blueprint $table) {
$table->id();
$table->string('name', 100);
$table->timestamps();
});
}
マイグレーションファイルの編集が終われば,マイグレーションを実行してデータベースにテーブルを作成します.なお,最初に php artisan migrate status
でマイグレーションの実行状況を確認してからマイグレーションを実行すると良いでしょう.今回の場合は campuses と faculties のテーブルがすでに作成ずみであるので,php artisan migrate
コマンドでは students と lectures のテーブル作成だけが実行されました.
vagrant@ubuntu2204 laravelRelationship $ php artisan migrate:status ⏎ Migration name .................................... Batch / Status 2014_10_12_000000_create_users_table ..................... [1] Ran 2014_10_12_100000_create_password_reset_tokens_table ..... [1] Ran 2019_08_19_000000_create_failed_jobs_table ............... [1] Ran 2019_12_14_000001_create_personal_access_tokens_table .... [1] Ran 2023_10_17_131656_create_campuses_table .................. [1] Ran 2023_10_17_131720_create_faculties_table ................. [1] Ran 2023_10_17_162040_create_students_table .................. Pending 2023_10_17_162102_create_lectures_table .................. Pending vagrant@ubuntu2204 laravelRelationship $ php artisan migrate ⏎ INFO Running migrations. 2023_10_17_162040_create_students_table ................ 13ms DONE 2023_10_17_162102_create_lectures_table ................. 5ms DONE vagrant@ubuntu2204 laravelRelationship $ php artisan migrate:status ⏎ Migration name .................................... Batch / Status 2014_10_12_000000_create_users_table ..................... [1] Ran 2014_10_12_100000_create_password_reset_tokens_table ..... [1] Ran 2019_08_19_000000_create_failed_jobs_table ............... [1] Ran 2019_12_14_000001_create_personal_access_tokens_table .... [1] Ran 2023_10_17_131656_create_campuses_table .................. [1] Ran 2023_10_17_131720_create_faculties_table ................. [1] Ran 2023_10_17_162040_create_students_table .................. [2] Ran 2023_10_17_162102_create_lectures_table .................. [2] Ran vagrant@ubuntu2204 laravelRelationship $
多対多のリレーションシップを実現するには,2つのテーブルを繋ぐ中間テーブルが必要になります.Laravel では多対多を実現するには,テーブル名を単数にしつつ,アルファベット順に並べ,アンダースコアで区切った名前で中間テーブルを準備しなければならないというルールがあります.つまり,「students」テーブルと「lectures」テーブルでは「lecture_student」という中間テーブル名になります.
このルールに従った「lecture_student」テーブルを生成するためのマイグレーションファイルを作成します.
vagrant@ubuntu2204 laravelRelationship $ pwd ⏎ /home/vagrant/Documents/laravel/laravelRelationship vagrant@ubuntu2204 laravelRelationship $ php artisan make:migration create_lecture_student_table --create=lecture_student ⏎ INFO Migration [database/migrations/2023_10_17_162504_create_lecture_student_table.php] created successfully. vagrant@ubuntu2204 laravelRelationship $
マイグレーションファイルを編集します.20行目と25行目が外部キーの設定です.どちらのリレーションシップにも onDelete('cascade')
によってカスケード削除(連鎖削除)が設定されています.したがって,ある講義の情報を削除するとその操作に伴って中間テーブルからその講義の履修情報が全て連鎖的に削除されます.また,ある学生の退学に伴い情報を削除するとその操作に伴って中間テーブルからその学生の履修情報が全て連鎖的に削除されます.
database/migrations/2023_10_17_162504_create_lecture_student_table.php
<?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('lecture_student', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('lecture_id');
$table->unsignedBigInteger('student_id');
$table->timestamps();
$table->foreign('lecture_id')
->references('id')
->on('lectures')
->onDelete('cascade');
$table->foreign('student_id')
->references('id')
->on('students')
->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('lecture_student');
}
};
マイグレーションファイルの編集ができれば実際にマイグレーションを実行します.今度は中間テーブルの作成だけが実行されました.
vagrant@ubuntu2204 laravelRelationship $ php artisan migrate:status ⏎ Migration name .................................... Batch / Status 2014_10_12_000000_create_users_table ..................... [1] Ran 2014_10_12_100000_create_password_reset_tokens_table ..... [1] Ran 2019_08_19_000000_create_failed_jobs_table ............... [1] Ran 2019_12_14_000001_create_personal_access_tokens_table .... [1] Ran 2023_10_17_131656_create_campuses_table .................. [1] Ran 2023_10_17_131720_create_faculties_table ................. [1] Ran 2023_10_17_162040_create_students_table .................. [2] Ran 2023_10_17_162102_create_lectures_table .................. [2] Ran 2023_10_17_162504_create_lecture_student_table ........... Pending vagrant@ubuntu2204 laravelRelationship $ php artisan migrate ⏎ INFO Running migrations. 2023_10_17_162504_create_lecture_student_table ......... 13ms DONE vagrant@ubuntu2204 laravelRelationship $ php artisan migrate:status ⏎ Migration name .................................... Batch / Status 2014_10_12_000000_create_users_table ..................... [1] Ran 2014_10_12_100000_create_password_reset_tokens_table ..... [1] Ran 2019_08_19_000000_create_failed_jobs_table ............... [1] Ran 2019_12_14_000001_create_personal_access_tokens_table .... [1] Ran 2023_10_17_131656_create_campuses_table .................. [1] Ran 2023_10_17_131720_create_faculties_table ................. [1] Ran 2023_10_17_162040_create_students_table .................. [2] Ran 2023_10_17_162102_create_lectures_table .................. [2] Ran 2023_10_17_162504_create_lecture_student_table ........... [3] Ran vagrant@ubuntu2204 laravelRelationship $
3つのテーブルのシーダを生成します.
vagrant@ubuntu2204 laravelRelationship $ php artisan make:seeder StudentsTableSeeder ⏎ INFO Seeder [database/seeders/StudentsTableSeeder.php] created successfully. vagrant@ubuntu2204 laravelRelationship $ php artisan make:seeder LecturesTableSeeder ⏎ INFO Seeder [database/seeders/LecturesTableSeeder.php] created successfully. vagrant@ubuntu2204 laravelRelationship $ php artisan make:seeder LectureStudentTableSeeder ⏎ INFO Seeder [database/seeders/LectureStudentTableSeeder.php] created successfully. vagrant@ubuntu2204 laravelRelationship $
次に,学生テーブル,講義テーブルと中間テーブルにテスト用のデータを記載します.
database/seeders/StudentsTableSeeder.php
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class StudentsTableSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
// 一旦中身を削除する
DB::table('students')->delete();
DB::table('students')->insert([
'name' => '井上'
]);
DB::table('students')->insert([
'name' => '藤井'
]);
DB::table('students')->insert([
'name' => '飯田'
]);
DB::table('students')->insert([
'name' => '足立'
]);
DB::table('students')->insert([
'name' => '武田'
]);
}
}
database/seeders/LecturesTableSeeder.php
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class LecturesTableSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
// 一旦中身を削除する
DB::table('lectures')->delete();
DB::table('lectures')->insert([
'name' => '経営戦略論'
]);
DB::table('lectures')->insert([
'name' => '管理会計'
]);
DB::table('lectures')->insert([
'name' => '情報ネットワーク論'
]);
}
}
database/seeders/LectureStudentTableSeeder.php
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class LectureStudentTableSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
// 一旦中身を削除する
DB::table('lecture_student')->delete();
DB::table('lecture_student')->insert([
'lecture_id' => 1,
'student_id' => 1
]);
DB::table('lecture_student')->insert([
'lecture_id' => 2,
'student_id' => 1
]);
DB::table('lecture_student')->insert([
'lecture_id' => 1,
'student_id' => 2
]);
DB::table('lecture_student')->insert([
'lecture_id' => 3,
'student_id' => 2
]);
DB::table('lecture_student')->insert([
'lecture_id' => 1,
'student_id' => 3
]);
DB::table('lecture_student')->insert([
'lecture_id' => 2,
'student_id' => 3
]);
DB::table('lecture_student')->insert([
'lecture_id' => 3,
'student_id' => 3
]);
DB::table('lecture_student')->insert([
'lecture_id' => 2,
'student_id' => 4
]);
DB::table('lecture_student')->insert([
'lecture_id' => 3,
'student_id' => 4
]);
}
}
さらに DatabaseSeeder.php には今追加した3つのシーダを実行するコードを追加します.
database/seeders/DatabaseSeeder.php
<?php
namespace Database\Seeders;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*/
public function run(): void
{
$this->call(CampusesTableSeeder::class);
$this->call(FacultiesTableSeeder::class);
$this->call(StudentsTableSeeder::class);
$this->call(LecturesTableSeeder::class);
$this->call(LectureStudentTableSeeder::class);
}
}
シーダの準備ができたので,シーダを実行してテーブルにデータを投入します.このとき,php artisan db:seed
を実行すると,DatabaseSeeder.php に記載されたシーダが全て順番に実行されます.つまり,campuses や faculties はすでに投入済みであることから,これらが再び実行されてしまうことになる.これにより,1 番からスタートするはずの ID がずれてしまうなどの問題が発生する.このような場合は,まだ実行されていないシーダだけを実行するか,データベースを一旦すべてリセットしてからマイグレーション,シーダの順番に実行する方法がある.(ただし,本番環境でロールバックを実施しないように注意してください!)
まず,campuses や faculties にはデータがすでに格納されているので,新たな 3 つのシーダを順番に実行します.
vagrant@ubuntu2204 laravelRelationship $ php artisan db:seed --class=StudentsTableSeeder ⏎ INFO Seeding database. vagrant@ubuntu2204 laravelRelationship $ php artisan db:seed --class=LecturesTableSeeder ⏎ INFO Seeding database. vagrant@ubuntu2204 laravelRelationship $ php artisan db:seed --class=LectureStudentTableSeeder ⏎ INFO Seeding database. vagrant@ubuntu2204 laravelRelationship $
次は,データベースをロールバックしてから再度投入すること考えます.php artisan migrate:rollback
でデータベースのロールバックが可能です.しかし一度のロールバックでは直前のマイグレーションで生成されたテーブルだけがロールバックされます.したがって,マイグレーションの状況を確認しながら,ロールバックを何度か繰り返して全てのテーブルがリセットされたのを確認してからマイグレーションして,シーダを実行します.最後にはロールバック,マイグレーション,シーダの3つのコマンドを連続して実行しています.
vagrant@ubuntu2204 laravelRelationship $ php artisan migrate:status ⏎ Migration name ................................... Batch / Status 2014_10_12_000000_create_users_table .................... [1] Ran 2014_10_12_100000_create_password_reset_tokens_table .... [1] Ran 2019_08_19_000000_create_failed_jobs_table .............. [1] Ran 2019_12_14_000001_create_personal_access_tokens_table ... [1] Ran 2023_10_17_131656_create_campuses_table ................. [1] Ran 2023_10_17_131720_create_faculties_table ................ [1] Ran 2023_10_17_162040_create_students_table ................. [2] Ran 2023_10_17_162102_create_lectures_table ................. [2] Ran 2023_10_17_162504_create_lecture_student_table .......... [3] Ran vagrant@ubuntu2204 laravelRelationship $ php artisan migrate:rollback ⏎ INFO Rolling back migrations. 2023_10_17_162504_create_lecture_student_table ........ 10ms DONE vagrant@ubuntu2204 laravelRelationship $ php artisan migrate:status ⏎ Migration name ................................... Batch / Status 2014_10_12_000000_create_users_table .................... [1] Ran 2014_10_12_100000_create_password_reset_tokens_table .... [1] Ran 2019_08_19_000000_create_failed_jobs_table .............. [1] Ran 2019_12_14_000001_create_personal_access_tokens_table ... [1] Ran 2023_10_17_131656_create_campuses_table ................. [1] Ran 2023_10_17_131720_create_faculties_table ................ [1] Ran 2023_10_17_162040_create_students_table ................. [2] Ran 2023_10_17_162102_create_lectures_table ................. [2] Ran 2023_10_17_162504_create_lecture_student_table .......... Pending vagrant@ubuntu2204 laravelRelationship $ php artisan migrate:rollback ⏎ INFO Rolling back migrations. 2023_10_17_162102_create_lectures_table ............... 12ms DONE 2023_10_17_162040_create_students_table ................ 5ms DONE vagrant@ubuntu2204 laravelRelationship $ php artisan migrate:status ⏎ Migration name ................................... Batch / Status 2014_10_12_000000_create_users_table .................... [1] Ran 2014_10_12_100000_create_password_reset_tokens_table .... [1] Ran 2019_08_19_000000_create_failed_jobs_table .............. [1] Ran 2019_12_14_000001_create_personal_access_tokens_table ... [1] Ran 2023_10_17_131656_create_campuses_table ................. [1] Ran 2023_10_17_131720_create_faculties_table ................ [1] Ran 2023_10_17_162040_create_students_table ................. Pending 2023_10_17_162102_create_lectures_table ................. Pending 2023_10_17_162504_create_lecture_student_table .......... Pending vagrant@ubuntu2204 laravelRelationship $ php artisan migrate:rollback ⏎ INFO Rolling back migrations. 2023_10_17_131720_create_faculties_table .............. 11ms DONE 2023_10_17_131656_create_campuses_table ................ 4ms DONE 2019_12_14_000001_create_personal_access_tokens_table .. 5ms DONE 2019_08_19_000000_create_failed_jobs_table ............. 4ms DONE 2014_10_12_100000_create_password_reset_tokens_table ... 5ms DONE 2014_10_12_000000_create_users_table ................... 4ms DONE vagrant@ubuntu2204 laravelRelationship $ php artisan migrate:status ⏎ Migration name ................................... Batch / Status 2014_10_12_000000_create_users_table .................... Pending 2014_10_12_100000_create_password_reset_tokens_table .... Pending 2019_08_19_000000_create_failed_jobs_table .............. Pending 2019_12_14_000001_create_personal_access_tokens_table ... Pending 2023_10_17_131656_create_campuses_table ................. Pending 2023_10_17_131720_create_faculties_table ................ Pending 2023_10_17_162040_create_students_table ................. Pending 2023_10_17_162102_create_lectures_table ................. Pending 2023_10_17_162504_create_lecture_student_table .......... Pending vagrant@ubuntu2204 laravelRelationship $ php artisan migrate ⏎ INFO Running migrations. 2014_10_12_000000_create_users_table .................. 11ms DONE 2014_10_12_100000_create_password_reset_tokens_table ... 4ms DONE 2019_08_19_000000_create_failed_jobs_table ............. 8ms DONE 2019_12_14_000001_create_personal_access_tokens_table . 11ms DONE 2023_10_17_131656_create_campuses_table ................ 4ms DONE 2023_10_17_131720_create_faculties_table ............... 4ms DONE 2023_10_17_162040_create_students_table ................ 4ms DONE 2023_10_17_162102_create_lectures_table ................ 4ms DONE 2023_10_17_162504_create_lecture_student_table ......... 4ms DONE vagrant@ubuntu2204 laravelRelationship $ php artisan db:seed ⏎ INFO Seeding database. Database\Seeders\CampusesTableSeeder .................... RUNNING Database\Seeders\CampusesTableSeeder .............. 24.39 ms DONE Database\Seeders\FacultiesTableSeeder ................... RUNNING Database\Seeders\FacultiesTableSeeder ............. 40.01 ms DONE Database\Seeders\StudentsTableSeeder .................... RUNNING Database\Seeders\StudentsTableSeeder .............. 21.49 ms DONE Database\Seeders\LecturesTableSeeder .................... RUNNING Database\Seeders\LecturesTableSeeder .............. 12.29 ms DONE Database\Seeders\LectureStudentTableSeeder .............. RUNNING Database\Seeders\LectureStudentTableSeeder ........ 39.04 ms DONE vagrant@ubuntu2204 laravelRelationship $ php artisan migrate:rollback; php artisan migrate; php artisan db:seed; ⏎ INFO Rolling back migrations. 2023_10_17_162504_create_lecture_student_table ........ 16ms DONE 2023_10_17_162102_create_lectures_table ................ 6ms DONE 2023_10_17_162040_create_students_table ................ 5ms DONE 2023_10_17_131720_create_faculties_table ............... 5ms DONE 2023_10_17_131656_create_campuses_table ................ 5ms DONE 2019_12_14_000001_create_personal_access_tokens_table .. 6ms DONE 2019_08_19_000000_create_failed_jobs_table ............. 5ms DONE 2014_10_12_100000_create_password_reset_tokens_table ... 5ms DONE 2014_10_12_000000_create_users_table ................... 5ms DONE INFO Running migrations. 2014_10_12_000000_create_users_table .................. 11ms DONE 2014_10_12_100000_create_password_reset_tokens_table ... 4ms DONE 2019_08_19_000000_create_failed_jobs_table ............. 8ms DONE 2019_12_14_000001_create_personal_access_tokens_table . 12ms DONE 2023_10_17_131656_create_campuses_table ................ 4ms DONE 2023_10_17_131720_create_faculties_table ............... 5ms DONE 2023_10_17_162040_create_students_table ................ 4ms DONE 2023_10_17_162102_create_lectures_table ................ 4ms DONE 2023_10_17_162504_create_lecture_student_table ......... 4ms DONE INFO Seeding database. Database\Seeders\CampusesTableSeeder .................... RUNNING Database\Seeders\CampusesTableSeeder .............. 15.63 ms DONE Database\Seeders\FacultiesTableSeeder ................... RUNNING Database\Seeders\FacultiesTableSeeder ............. 71.50 ms DONE Database\Seeders\StudentsTableSeeder .................... RUNNING Database\Seeders\StudentsTableSeeder .............. 21.29 ms DONE Database\Seeders\LecturesTableSeeder .................... RUNNING Database\Seeders\LecturesTableSeeder .............. 12.77 ms DONE Database\Seeders\LectureStudentTableSeeder .............. RUNNING Database\Seeders\LectureStudentTableSeeder ........ 39.29 ms DONE vagrant@ubuntu2204 laravelRelationship $
シーダでデータの投入ができたので,sqlite3 で確認してみます.結合 (INNER JOIN
) によってどの学生がどの講義を履修しているのかが確認できました.
vagrant@ubuntu2204 laravelRelationship $ pwd ⏎ /home/vagrant/Documents/laravel/laravelRelationship vagrant@ubuntu2204 laravelRelationship $ ls ⏎ README.md bootstrap config phpunit.xml routes vendor app composer.json database public storage vite.config.js artisan composer.lock package.json resources tests vagrant@ubuntu2204 laravelRelationship $ cd database/ ⏎ vagrant@ubuntu2204 database $ ls ⏎ database.sqlite factories migrations seeders vagrant@ubuntu2204 database $ sqlite3 database.sqlite ⏎ SQLite version 3.38.2 2022-03-26 13:51:10 Enter ".help" for usage hints. sqlite> .tables ⏎ campuses lectures students faculties migrations users failed_jobs password_reset_tokens lecture_student personal_access_tokens sqlite> .headers ON ⏎ sqlite> SELECT * FROM students; ⏎ id|name|created_at|updated_at 1|井上|| 2|藤井|| 3|飯田|| 4|足立|| 5|武田|| sqlite> SELECT * FROM lectures; ⏎ id|name|created_at|updated_at 1|経営戦略論|| 2|管理会計|| 3|情報ネットワーク論|| sqlite> SELECT * FROM lecture_student; ⏎ id|lecture_id|student_id|created_at|updated_at 1|1|1|| 2|2|1|| 3|1|2|| 4|3|2|| 5|1|3|| 6|2|3|| 7|3|3|| 8|2|4|| 9|3|4|| sqlite> SELECT students.id, students.name, lectures.name ...> FROM students ...> INNER JOIN lecture_student ON ...> students.id = lecture_student.student_id ...> INNER JOIN lectures ON ...> lectures.id = lecture_student.lecture_id ...> ORDER BY students.id; ⏎ id|name|name 1|井上|経営戦略論 1|井上|管理会計 2|藤井|経営戦略論 2|藤井|情報ネットワーク論 3|飯田|経営戦略論 3|飯田|管理会計 3|飯田|情報ネットワーク論 4|足立|管理会計 4|足立|情報ネットワーク論 sqlite> .exit ⏎ vagrant@ubuntu2204 database $ cd .. ⏎ vagrant@ubuntu2204 laravelRelationship $
Student モデルと Lecture モデルを作成します.繰り返しになりますが,モデル名は先頭大文字の単数形で命名します.
vagrant@ubuntu2204 laravelRelationship $ pwd ⏎ /home/vagrant/Documents/laravel/laravelRelationship vagrant@ubuntu2204 laravelRelationship $ ls app/Models/ ⏎ Campus.php Faculty.php User.php vagrant@ubuntu2204 laravelRelationship $ php artisan make:model Student ⏎ INFO Model [app/Models/Student.php] created successfully. vagrant@ubuntu2204 laravelRelationship $ php artisan make:model Lecture ⏎ INFO Model [app/Models/Lecture.php] created successfully. vagrant@ubuntu2204 laravelRelationship $ ls app/Models/ ⏎ Campus.php Faculty.php Lecture.php Student.php User.php vagrant@ubuntu2204 laravelRelationship $
Student モデルと Lecture モデルに関連するコントローラを作成します.ここでもやはりコントローラ名は先頭大文字の複数形(または単数形)で命名することに注意していください.
vagrant@ubuntu2204 laravelRelationship $ ls app/Http/Controllers/ ⏎ CampusesController.php Controller.php FacultiesController.php vagrant@ubuntu2204 laravelRelationship $ php artisan make:controller StudentsController ⏎ INFO Controller [app/Http/Controllers/StudentsController.php] created successfully. vagrant@ubuntu2204 laravelRelationship $ php artisan make:controller LecturesController ⏎ INFO Controller [app/Http/Controllers/LecturesController.php] created successfully. vagrant@ubuntu2204 laravelRelationship $ ls app/Http/Controllers/ ⏎ CampusesController.php FacultiesController.php StudentsController.php Controller.php LecturesController.php vagrant@ubuntu2204 laravelRelationship $
まず,現時点でのルートの定義を確認します.
vagrant@ubuntu2204 laravelRelationship $ php artisan route:list ⏎
GET|HEAD / .......................................................................
POST _ignition/execute-solution ignition.executeSolution › Spatie\LaravelIgni…
GET|HEAD _ignition/health-check ignition.healthCheck › Spatie\LaravelIgnition › H…
POST _ignition/update-config ignition.updateConfig › Spatie\LaravelIgnition …
GET|HEAD api/user ................................................................
GET|HEAD campuses ...................... campuses.index › CampusesController@index
GET|HEAD faculties ................... faculties.index › FacultiesController@index
GET|HEAD sanctum/csrf-cookie sanctum.csrf-cookie › Laravel\Sanctum › CsrfCookieCo…
Showing [8] routes
vagrant@ubuntu2204 laravelRelationship $
/students と /lectures の URI が指定されたときに,それぞれのコントローラの index 関数が呼び出されるように routes/web にルートを定義します.
routes/web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\CampusesController;
use App\Http\Controllers\FacultiesController;
use App\Http\Controllers\StudentsController;
use App\Http\Controllers\LecturesController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "web" middleware group. Make something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Route::get('/campuses', [CampusesController::class, 'index']) -> name('campuses.index');
Route::get('/faculties', [FacultiesController::class, 'index']) -> name('faculties.index');
Route::get('/students', [StudentsController::class, 'index']) -> name('students.index');
Route::get('/lectures', [LecturesController::class, 'index']) -> name('lectures.index');
再びルートを確認します.
vagrant@ubuntu2204 laravelRelationship $ php artisan route:list ⏎
GET|HEAD / .......................................................................
POST _ignition/execute-solution ignition.executeSolution › Spatie\LaravelIgni…
GET|HEAD _ignition/health-check ignition.healthCheck › Spatie\LaravelIgnition › H…
POST _ignition/update-config ignition.updateConfig › Spatie\LaravelIgnition …
GET|HEAD api/user ................................................................
GET|HEAD campuses ...................... campuses.index › CampusesController@index
GET|HEAD faculties ................... faculties.index › FacultiesController@index
GET|HEAD lectures ...................... lectures.index › LecturesController@index
GET|HEAD sanctum/csrf-cookie sanctum.csrf-cookie › Laravel\Sanctum › CsrfCookieCo…
GET|HEAD students ...................... students.index › StudentsController@index
Showing [10] routes
vagrant@ubuntu2204 laravelRelationship $
app/Http/Controllers/ 以下の StudentsController.php と LecturesController.php に一覧表示の雛形を作成します.
app/HTTP/Controllers/StudentsController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class StudentsController extends Controller
{
public function index()
{
dd('List of Students');
}
}
app/HTTP/Controllers/LecturesController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class LecturesController extends Controller
{
public function index()
{
dd('List of Students');
}
}
Web サーバを起動して,実際に /students と /lectures にアクセスします.
vagrant@ubuntu2204 laravelRelationship $ php artisan serve --host=192.168.56.101 --port=8000
INFO Server running on [http://192.168.56.101:8000].
Press Ctrl+C to stop the server
ようやくリレーションシップを設定する準備ができました.ある学生が履修することのできる講義は複数あり,ある講義は複数の学生が履修することができるので,「学生と講義の関係は多対多」になります.一対多の場合と似ていますが,「学生 (Student)」クラスでは,その学生が履修している講義のリストを取得する lectures メソッドを定義します.同様に「講義 (Lecture)」クラスでも,その講義を履修している学生のリストを取得するための students メソッドを定義します.次のようにそれぞれのモデルに belongsToMany()
を使ってリレーションシップを指定します.
app/Models/Student.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Student extends Model
{
use HasFactory;
// Many to Many
public function lectures()
{
return $this->belongsToMany('App\Models\Lecture');
}
}
app/Models/Lecture.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Lecture extends Model
{
use HasFactory;
// Many to Many
public function students()
{
return $this->belongsToMany('App\Models\Student');
}
}
モデルにリレーションシップのメソッドを記載できたら,次はコントローラから呼び出してみます.
app/HTTP/Controllers/StudentsController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Student;
class StudentsController extends Controller
{
public function index()
{
$students = Student::get();
foreach ($students as $student) {
dump("+++++++++++++++");
dump($student->name);
foreach($student->lectures as $lecture) {
dump($lecture->name);
}
}
}
}
app/HTTP/Controllers/LecturesController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Lecture;
class LecturesController extends Controller
{
public function index()
{
$lectures = Lecture::get();
foreach ($lectures as $lecture) {
dump("+++++++++++++++");
dump($lecture->name);
foreach($lecture->students as $student) {
dump($student->name);
}
}
}
}
Web サーバを起動して,実際に /students と /lectures にアクセスします.
vagrant@ubuntu2204 laravelRelationship $ php artisan serve --host=192.168.56.101 --port=8000
INFO Server running on [http://192.168.56.101:8000].
Press Ctrl+C to stop the server