Laravel migrationまわり

migrationファイルを使ってテーブルやカラムを操作したり、seederやfactoryやfakerを使ってレコードを挿入したり、modelをリレーションさせたりします。


## 前提
- composerインストール済み
- Laravelインストール済み
- データベース、ユーザー作成済み
- ユーザーのDB接続情報を.envファイルに記述済み

Laravelのインストールについては、下記の記事を参照してください。
[Laravelのインストール、初期設定、GitHubの使用](https://qiita.com/takeshisakuma/items/44055d362e2f3e8da3d9)


## テーブルの作成
3つのテーブルを作成していきます。

### 作成するテーブルのカラム
学校(schools)テーブル

|id|name|email|created_at|updated_at|
|---|---|---|---|---|
|ID|学校名|メールアドレス|作成日時|更新日時|


クラス(classnames)テーブル

|id|name|created_at|updated_at|
|---|---|---|---|
|ID|クラス名|作成日時|更新日時|


ゴミ(trashes)テーブル

|id|name|DayOfTheWeek|created_at|updated_at|
|---|---|---|---|---|
|ID|ゴミの種類|回収の曜日|作成日時|更新日時|


### modelファイルの作成
```:terminal
//php artisan make:model Models/モデル名 -m
 
php artisan make:model Models/School -m
php artisan make:model Models/Classname -m
php artisan make:model Models/Trash -m
```

|オプション|内容|
|---|---|
|-m|migrationファイルも同時作成|
|-mc|migrationファイルとcontrollerファイルも同時作成|

下記の6ファイルが作成されます。

- app\Models\School.php
- app\Models\Classname.php
- app\Models\Trash.php
- database\migrations\xxxx_xx_xx_xxxxxx_create_schools_table.php
- database\migrations\xxxx_xx_xx_xxxxxx_create_classnames_table.php
- database\migrations\xxxx_xx_xx_xxxxxx_create_trashes_table.php

### migrationファイルの編集
migrationファイルを使用すると、phpMyAdminなどでのGUIでの操作ではなく、操作履歴をファイルで管理できます。

|up/down|記述すること|テーブル作成時の場合|
|---|---|---|
|up|migrationを実行した際の処理|作成するテーブルの情報を記述|
|down|upの処理を取り消す記述|テーブル削除を記述|



```:database\migrations\xxxx_xx_xx_xxxxxx_create_schools_table.php
public function up()
  {
    Schema::create('schools', function (Blueprint $table) {
      $table->id()->autoIncrement();
      $table->string('name');
      $table->string('email');
      $table->timestamps();
     });
  }
 
public function down()
  {
    Schema::dropIfExists('schools');
  }
```






```:database\migrations\xxxx_xx_xx_xxxxxx_create_classnames_table.php
public function up()
  {
    Schema::create('classnames', function (Blueprint $table) {
      $table->id()->autoIncrement();
      $table->string('name');
      $table->timestamps();
    });
  }
   
public function down()
    {
      Schema::dropIfExists('classnames');
    }
```

```:database\migrations\xxxx_xx_xx_xxxxxx_create_trashes_table.php
public function up()
  {
    Schema::create('trashes', function (Blueprint $table) {
      $table->id()->autoIncrement();
      $table->string('name');
      $table->enum('DayOfTheWeek', ['月曜', '火曜', '水曜', '木曜', '金曜']);
      $table->timestamps();
  });
}

public function down()
  {
    Schema::dropIfExists('trashes');
  }
```





### migrarionの実行

```:terminal
php artisan migrate
```
schools、classnames、trashesの3つのテーブルが作成されます。

## テーブルのリネーム
trashesテーブルという名前のテーブルを作りましたが、やっぱりgarbagesテーブルという名前に変更したくなったので、変更してみます。

### migrationファイルの作成

```:terminal
//php artisan make:migration マイグレーションファイル名 --table=変更したいテーブル名
 
php artisan make:migration rename_trashes_table_to_garbages_table --table=trashes
```

### migrationファイルの編集

```:database\migrations\2020_08_15_185925_rename_trashes_table_to_garbages_table.php
public function up()
  {
    Schema::table('trashes', function (Blueprint $table) {
      Schema::rename('trashes', 'garbages');
    });
  }

public function down()
  {
    Schema::table('trashes', function (Blueprint $table) {
      Schema::rename('garbages', 'trashes');
    });
  }
```


### migrationの実行

```:terminal
php artisan migrate
```
trashesテーブルの名前がgarbagesテーブルに変更されます。




## カラム追加
schoolsテーブルにtel(電話番号)のカラムを追加します。

### migrationファイルの作成

```:terminal
//php artisan make:migration マイグレーションファイル名 --table=テーブル名

php artisan make:migration add_tel_to_schools_table --table=schools
```
database\migrations\xxxx_xx_xx_xxxxxx_add_tel_to_schools_table.phpが作成されます。

### migrationファイルの編集
schoolsテーブルのnameカラムの後にtelカラムを追加します。

```:database\migrations\xxxx_xx_xx_xxxxxx_add_tel_to_schools_table.php
public function up()
  {
    Schema::table('schools', function (Blueprint $table) {
      $table->string('tel')->after('name');
    });
  }
  
public function down()
  {
    Schema::table('schools', function (Blueprint $table) {
      $table->dropColumn('tel');
    });
  }
```


### migrationの実行

```:terminal
php artisan migrate
```

schoolsテーブルの、nameカラムの後にtelカラムが追加されました。



## カラム操作の準備
カラムの変更には下記のパッケージのインストールが必要になるので、インストールしておきます。

### doctrine/dbalパッケージのインストール

```:terminal
composer require doctrine/dbal
```






## カラムのリネーム
telというカラムを作成しましたが、やはりtelephoneという名前に変更したくなったので、変更していきます。

### migrationファイルの作成

```:terminal
//php artisan make:migration マイグレーションファイル名 --table=テーブル名

php artisan make:migration rename_tel_column_to_telephone_on_schools_table --table=schools
```
database\migrations\xxxx_xx_xx_xxxxxx_rename_tel_column_to_telephone_on_schools_table.phpが作成されます。

### migrationファイルの編集

```:database\migrations\xxxx_xx_xx_xxxxxx_rename_tel_column_to_telephone_on_schools_table.php
public function up()
  {
    Schema::table('schools', function (Blueprint $table) {
      $table->renameColumn('tel', 'telephone');
      });
   }

public function down()
  {
    Schema::table('schools', function (Blueprint $table) {
      $table->renameColumn('telephone', 'tel');
    });
  }
```

### migrationの実行

```:terminal
php artisan migrate
```

schoolsテーブルの、telカラムの名前がtelephoneカラムに変更されます。





## カラムの属性変更

### カラムのデータの長さの変更
255から11に変更します。

### migrationファイルの作成


```:terminal
//php artisan make:migration マイグレーションファイル名 --table=テーブル名

php artisan make:migration change_length_telephone_culumn_on_schools_table --table=schools
```
database\migrations\xxxx_xx_xx_xxxxxx_change_length_telephone_culumn_on_schools_table.phpが作成されます。

### migrationファイルの編集


```:database\migrations\xxxx_xx_xx_xxxxxx_change_length_telephone_culumn_on_schools_table.php
public function up()
  {
    Schema::table('schools', function (Blueprint $table) {
      $table->string('telephone', 11)->change();
    });
  }

public function down()
  {
    Schema::table('schools', function (Blueprint $table) {
      $table->string('telephone', 255)->change();
  });
}
```

### migrationの実行

```:terminal
php artisan migrate
```

schoolsテーブルの、telephoneカラムの長さが255から11に変更されます。


## カラムのデータ型の変更
schoolsテーブルの、telephoneカラムのデータ型を、文字列から数値に変更してみます。

### migrationファイルの作成

```:terminal
//php artisan make:migration マイグレーションファイル名 --table=テーブル名

php artisan make:migration change_telehone_column_string_to_integer_on_schools_table --table=schools
```

telephoneカラムを文字列から数値に変更します。

### migrationファイルの編集

```:database\migrations\xxxx_xx_xx_xxxxxx_change_telehone_column_string_to_integer_on_schools_table.php
public function up()
  {
    Schema::table('schools', function (Blueprint $table) {
      $table->integer('telephone')->change();
      });
  }
  
public function down()
  {
    Schema::table('schools', function (Blueprint $table) {
      $table->string('telephone')->change();
      });
  }
```

### migrationの実行

```:terminal
php artisan migrate
```
telephoneカラムが文字列型から数値型に変更されます。

## カラム削除
やはり電話番号は掲載しない事にしたので、telephoneカラムを削除します。

### migrationファイルの作成

```:terminal
//php artisan make:migration マイグレーションファイル名 --table=テーブル名

php artisan make:migration drop_tel_from_schools_table --table=schools
```

### migrationファイルの編集

```:database\migrations\xxxx_xx_xx_xxxxxx_drop_tel_from_schools_table.php
public function up()
  {
    Schema::table('schools', function (Blueprint $table) {
      $table->dropColumn('telephone');
    });
  }
      
public function down()
  {
    Schema::table('schools', function (Blueprint $table) {
      $table->string('telephone')->after('name');
    });
  }
```



### migrationの実行

```:terminal
php artisan migrate
```
telephoneカラムが削除されます。




## レコード作成
seederを使ってテーブルにレコードを挿入します。

### seederファイルの作成

```:terminal
//php artisan make:seeder シーダーファイル名

php artisan make:seeder SchoolsTableSeeder

php artisan make:seeder ClassnamesTableSeeder

php artisan make:seeder GarbagesTableSeeder
```

Seederファイルが3つ作成されます。

- database\seeds\SchoolsTableSeeder.php
- database\seeds\ClassnamesTableSeeder.php
- database\seeds\GarbegesTableSeeder.php


### seederファイルの編集

```:database\seeds\SchoolsTableSeeder.php
public function run()
  {
    DB::table("schools")->insert(
      [
        [
          'name'=>'北高校',
          'email'=>Str::random(10)."@kitako.com",
          'created_at'=>now(),
          'updated_at'=>now(),
        ],
        [
          'name'=>'南高校',
          'email'=>Str::random(10)."@minamiko.com",
          'created_at'=>now(),
          'updated_at'=>now(),
        ],
        [
          'name'=>'西高校',
          'email'=>Str::random(10)."@nishiko.com",
          'created_at'=>now(),
          'updated_at'=>now(),
        ],
        [
          'name'=>'東高校',
          'email'=>Str::random(10)."@higashiko.com",
          'created_at'=>now(),
          'updated_at'=>now(),
        ],
        ]
      );
    }
```


```:database\seeds\ClassnamesTableSeeder.php
public function run()
  {
    DB::table("classnames")->insert(
      [
        [
          'name'=>'1-A',
           'created_at'=>now(),
             'updated_at'=>now(),
           ],
           [
             'name'=>'1-B',
             'created_at'=>now(),
             'updated_at'=>now(),
           ],
           [
             'name'=>'1-C',
             'created_at'=>now(),
             'updated_at'=>now(),
           ],
           [
             'name'=>'2-A',
             'created_at'=>now(),
             'updated_at'=>now(),
           ],
           [
             'name'=>'2-B',
             'created_at'=>now(),
             'updated_at'=>now(),
           ],
           [
             'name'=>'2-C',
             'created_at'=>now(),
             'updated_at'=>now(),
           ],
           [
             'name'=>'3-A',
             'created_at'=>now(),
             'updated_at'=>now(),
           ],
           [
             'name'=>'3-B',
             'created_at'=>now(),
             'updated_at'=>now(),
           ],
           [
             'name'=>'3-C',
             'created_at'=>now(),
             'updated_at'=>now(),
           ],
         ]
         );
     }
```

```:database\seeds\GarbagesTableSeeder.php
public function run()
  {
    DB::table("garbages")->insert(
      [
        [
          'name'=>'可燃物',
          'DayOfTheWeek'=>'月曜',
          'created_at'=>now(),
          'updated_at'=>now(),
        ],
        [
          'name'=>'不燃物',
          'DayOfTheWeek'=>'火曜',
          'created_at'=>now(),
          'updated_at'=>now(),
        ],
        [
          'name'=>'ペットボトル',
          'DayOfTheWeek'=>'水曜',
          'created_at'=>now(),
          'updated_at'=>now(),
        ],
        [
          'name'=>'ビン',
          'DayOfTheWeek'=>'木曜',
          'created_at'=>now(),
          'updated_at'=>now(),
        ],
        [
          'name'=>'カン',
          'DayOfTheWeek'=>'金曜',
          'created_at'=>now(),
          'updated_at'=>now(),
        ],
      ]
    );
  }

```




### 使用するseederファイルの追加
seederファイル作成だけでは実行時に反映されないので、database\seeds\DatabaseSeeder.phpに、新しく作成した3つのseederを追加します。

```:database\seeds\DatabaseSeeder.php
public function run()
  {
    //追加
    $this->call(SchoolsTableSeeder::class);
    $this->call(ClassnamesTableSeeder::class);
    $this->call(GarbagesTableSeeder::class);
  }
``` 

### seederの実行

```:terminal
//seeder実行
php artisan db:seed
```
3つのテーブルにレコードが挿入されます。


## テーブル削除
実はgarbagesテーブルは必要なかったので削除していきます。

### migrationファイルの作成

```:terminal
//php artisan make:migration マイグレーションファイル名

php artisan make:migration drop_garbages_table
```

xxxx_xx_xx_xxxxxx_drop_garbages_table.phpが作成されます。


### migrationファイルの編集

```:database\migrations\xxxx_xx_xx_xxxxxx_drop_garbages_table.php
public function up()
  {
    Schema::dropIfExists('garbages');
  }
 
public function down()
  {       
    Schema::create('garbages', function (Blueprint $table) {
      $table->id()->autoIncrement();
      $table->string('name');
      $table->enum('DayOfTheWeek', ['月曜', '火曜', '水曜', '木曜', '金曜']);
      $table->timestamps();
    });
  }
```


### migrationの実行
```:terminal
php artisan migrate
```
garbagesテーブルが削除されます。














## 子テーブル作成
これまでに作成した学校テーブル、クラステーブルを親に持つテーブルを作成していきます。


### 作成するテーブルのカラム
生徒(student)テーブル

|id|name|school_id|classname_is|created_at|updated_at|
|---|---|---|---|---|---|
|ID|生徒の名前|学校ID(学校テーブルのIDカラム)|クラスID(クラステーブルのIDカラム)|作成日時|更新日時|


### modelファイルの作成

```:terminal
php artisan make:model Models/Student -m
``` 

下記の2ファイルが作成されます。
app\Models\student.php
database\migrations\xxxx_xx_xx_xxxxxx_create_students_table.php



### migrationファイルの編集

```:database\migrations\xxxx_xx_xx_xxxxxx_create_students_table.php
public function up()
  {
    Schema::create('students', function (Blueprint $table) {
      $table->id()->autoIncrement();
      $table->string('name');
      $table->string('email');
      $table->string('telephone');
      $table->string('address');
      $table->unsignedBigInteger('school_id');
      $table->unsignedBigInteger('classname_id');
      $table->timestamps();
 
      //school_idの外部キーとしてschoolsテーブルのidカラムを指定
      $table->foreign('school_id')
        ->references('id')->on('schools')
        ->onDelete('restrict')
        ->onUpdate('cascade');
 
      //classname_idの外部キーとしてclassnamesテーブルのidカラムを指定
      $table->foreign('classname_id')
        ->references('id')->on('classnames')
        //classnamesテーブルのidが削除されたときの挙動の指定
        ->onDelete('restrict')
        //classnamesテーブルのidが変更されたときの挙動の指定
        ->onUpdate('cascade');                       
    });
  }
   
public function down()
  {
    Schema::dropIfExists('students');
  }
```


#### 変更時の挙動のオプション
すでに子テーブル側で使用されている親テーブルの値を削除、変更する場合の挙動を指定できます。

- 「デリート時(on delete)」
- 「更新時(on update)」

||UPDATE|DELETE|
|---|---|---|
|RESTRICT|エラー|エラー|
|CASCADE|参照先の変更に従う(値の変更)|参照先の変更に従う(削除)|
|SET NULL|NULLをセット|NULLをセット|
|NO ACTION|RESTRICTと同じ|RESTRICTと同じ|








### migrationの実行

```:terminal
php artisan migrate
```
studentsテーブルが作成されます。


## レコードの作成
fakerを使って、ダミーデータにそれっぽい値を入れることができます。

### fakerの日本向けローカライズ
作成するダミーデータを日本向けにできます。

```:config\app.php
'faker_locale' => 'en_US',
//↓変更
'faker_locale' => 'ja_JP',
```

### factoryファイルの作成

```:terminal
//php artisan make:factory ファクトリーファイル名 --model=モデルのパス

php artisan make:factory StudentFactory --model=Models\Student
```

database\factories\StudentsFactory.phpが新規作成されます。


### factoryファイルの編集

```:database\factories\StudentsFactory.php

$factory->define(Student::class, function (Faker $faker) {
 
  //追加
  $schools = App\Models\School::pluck('id')->toArray();
  $classnames = App\Models\Classname::pluck('id')->toArray();
 
  return [
  
    //追加
    'name'=>$faker->Name(20),
    'email'=>$faker->email(255),
    'address'=>$faker->address(255),
    'telephone'=>$faker->phoneNumber(11),
    'school_id' => $faker->randomElement($schools),
    'classname_id' => $faker->randomElement($classnames),

  ];
});
``` 



### seeederファイル作成

```:terminal
//php artisan make:seeder シーダーファイル名

php artisan make:seeder StudentsTableSeeder
```
 
database\seeds\StudentsTableSeeder.phpが新規作成されます。


### seeederファイル編集

```:database\seeds\StudentsTableSeeder.php
//model追加
use App\Models\Student;
 
class StudentsTableSeeder extends Seeder
  {
    public function run()
      {
        //登録するレコード数を指定(10件のデータを作成する場合)
        factory(Student::class, 10)->create();
       }
  }
```


### DatabaseSeeder.phpの変更

```:database\seeds\DatabaseSeeder.php
public function run()
  {
    $this->call(ClassnamesTableSeeder::class);
    $this->call(SchoolsTableSeeder::class);
         
    //削除(Garbagesテーブルを削除したため)
    //$this->call(GarbagesTableSeeder::class);
         
    //追加
    $this->call(StudentsTableSeeder::class);
  }
``` 

### seeder実行

```:terminal
php artisan db:seed
```
学生テーブルにレコードが挿入されます。





## リレーション(一対多の場合)
Model同士の関連付けを行います。
SchoolとStudent、ClassnameとStudentはそれぞれ一対多の関係なので、hasManyとbelongsToを使います。


### modelファイルの編集



```:App/Models/Shool.php 
class School extends Model
 {
    //親テーブルのモデルのメソッド名は複数形にしておく
    public function students(){
      return $this->hasMany('App\Models\Student');
    }
  }
```

```:App/Models/Classname.php
class Classname extends Model
  {
    //子テーブルのモデルを関連付けるメソッド名は単数形にしておく
    public function students()
      {
        return $this->hasMany('App\Models\Student');
      }
  }
```


```:App/Models/Student.php
class Student extends Model
  {
    //子テーブルのモデルのメソッド名は単数形にしておく
    public function school()
      {
        return $this->belongsTo('App\Models\School');
      }
 
    //子テーブルのモデルのメソッド名は単数形にしておく
    public function classname()
      {
        return $this->belongsTo('App\Models\Classname');
      }
  }
```


## リレーションの動作確認

### controllerファイルの作成


```:terminal
php artisan make:controller StudentController
```
app\Http\Controllers\StudentController.phpが作成されます。


### controllerファイルの編集
```:app\Http\Controllers\StudentController.php
//追加
use App\Models\Student;
 
class StudentController extends Controller
  {
    //追加
    public function getSchool()
      {
        //生徒のIDを指定
        $student_id=2;
 
        //生徒IDから生徒名を取得
        $student_name=student::find($student_id)->name;
 
        //生徒IDから生徒の学校名を取得
        $school_id=student::find($student_id)->school->id;
        $school_name=student::find($student_id)->school->name;
 
        return('生徒ID'.$student_id.'の'.$student_name.'が通っている学校は、学校ID'.$school_id.'の'.$school_name.'です。');
      }
 
    //追加
    public function getClassname()
      {
        //生徒のIDを指定
        $student_id=3;
 
        //生徒IDから生徒名を取得
        $student_name=student::find($student_id)->name;
 
        //生徒IDから生徒のクラス名を取得
        $classname_id=student::find($student_id)->classname->id;
        $classname_name=student::find($student_id)->classname->name;
 
        return('生徒ID'.$student_id.'の'.$student_name.'のクラスは、クラス名ID'.$classname_id.'の'.$classname_name.'です。');
      }
 
 }
``` 


### ルーティングの追加

- student/classnameにブラウザでアクセスすると、StudentControllerで作成したgetClassnameメソッドを実行
- student/schoolにブラウザでアクセスすると、StudentControllerで作成したgetSchoolメソッドを実行

```:routes/web.php
//追加
Route::get('student/school', 'StudentController@getSchool');
Route::get('student/classname', 'StudentController@getClassname');
```  

### 表示確認
#### 簡易サーバーの起動

```:terminal
php artisan serve
```

#### Webブラウザでアクセスする
http://127.0.0.1:8000/student/school
http://127.0.0.1:8000/student/classname

#### 簡易サーバーの停止
terminalでCtrl+Cを押します。




## テーブル作成
新しく講義テーブルを作っていきます。

### 作成するテーブルのカラム
講義(lectures)テーブル

|id|name|created_at|updated_at|
|---|---|---|---|
|ID|講義名|作成日時|更新日時|


### modelファイルの作成

```:terminal
//php artisan make:model Models/モデル名 -m

php artisan make:model Models/Lecture -m
``` 

下記の2ファイルが作成されます。

- app\Models\Lecture.php
- database\migrations\xxxx_xx_xx_xxxxxx_create_lectures_table.php






### migrationファイルの編集


```:database\migrations\xxxx_xx_xx_xxxxxx_create_lectures_table.php
public function up()
  {
    Schema::create('lectures', function (Blueprint $table) {
      $table->id();
      $table->string('name');
      $table->timestamps();
        });
      }

public function down()
  {
    Schema::dropIfExists('lectures');
  }
```

### migrationの実行

```:terminal
php artisan migrate
```










## lecturesテーブルのレコード作成

### seederファイルの作成

```:terminal
//php artisan make:seeder シーダーファイル名

php artisan make:seeder LecturesTableSeeder
```

seederファイルが1つ作成されます。
- database\seeds\LecturesTableSeeder.php



### seederファイルの編集

```:database\seeds\LecturesTableSeeder.php
public function run()
  {
    DB::table("lectures")->insert(
      [
        [
          'name'=>'国語',
          'created_at'=>now(),
          'updated_at'=>now(),
        ],
        [
          'name'=>'英語',
          'created_at'=>now(),
          'updated_at'=>now(),
        ],
        [
          'name'=>'数学',
          'created_at'=>now(),
          'updated_at'=>now(),
        ],
        [
          'name'=>'歴史',
           'created_at'=>now(),
           'updated_at'=>now(),
        ],
        [
          'name'=>'公民',
          'created_at'=>now(),
          'updated_at'=>now(),
        ],
        [
          'name'=>'政治',
          'created_at'=>now(),
          'updated_at'=>now(),
        ],
      ]
    );
  }
```


### DatabaseSeeder.phpの変更
DatabaseSeeder.phpに、新しく作成したseederを追加します。

```:database\seeds\DatabaseSeeder.php
public function run()
  {
    $this->call(ClassnamesTableSeeder::class);
    $this->call(SchoolsTableSeeder::class);
    $this->call(StudentsTableSeeder::class);
         
    //追加
    $this->call(LecturesTableSeeder::class);
  }
```



### seederの実行

```:terminal
php artisan db:seed
```
lecturesテーブルにレコードが挿入されます。

















## 中間テーブルの作成
講義テーブルと生徒テーブルは多対多の関係なので、中間テーブルを作ります。
中間テーブルにはモデル作成は不要です。
中間テーブルはstudentsとlecturesの関係だけを記述していきます。



中間(student_lecture)テーブル

|id|lecture_id|student_id|created_at|updated_at|
|---|---|---|---|---|
|ID|生徒ID|講義ID|作成日時|更新日時|



### migrationファイルの作成

中間テーブルはモデル作成不要なので、いきなりmigrationファイルを作ります。

```:terminal
php artisan make:migration create_lecture_student_table
```
database\migrations\2020_08_15_223620_create_lecture_student_table.phpが作成されます。

### migrationファイルの編集

```:database\migrations\2020_08_15_223620_create_lecture_student_table.php
    public function up()
    {
        Schema::create('lecture_student', function (Blueprint $table) {
            $table->unsignedBigInteger('lecture_id');
            $table->unsignedBigInteger('student_id');

            //lecture_idとstudent_idで複合キーに指定
            $table->primary(['lecture_id','student_id']);
            $table->timestamps();

            //lecture_idの外部キーとしてlecturesテーブルのidカラムを指定
            $table->foreign('lecture_id')
                        ->references('id')->on('lectures')
                        ->onDelete('restrict')
                        ->onUpdate('cascade');

            //student_idの外部キーとしてstudentテーブルのidカラムを指定
            $table->foreign('student_id')
            ->references('id')->on('students')
            ->onDelete('restrict')
            ->onUpdate('cascade');
        });
    }

    public function down()
    {
        Schema::dropIfExists('lecture_student');
    }
```

### migrationの実行

```:terminal
php artisan migrate
```
student_lectureテーブルが作成されます。

### seederファイルの作成

```:terminal
php artisan make:seed LectureStudentTableSeeder
```
database\seeds\LectureStudentTableSeeder.phpが作成されます。


### seederファイルの編集

```:database\seeds\LectureStudentTableSeeder.php
public function run()
  {
    DB::table("lecture_student")->insert(
      [
        [
          'lecture_id'=>6,
          'student_id'=>1,
          'created_at'=>now(),
          'updated_at'=>now(),
        ],
        [
          'lecture_id'=>4,
          'student_id'=>1,
          'created_at'=>now(),
          'updated_at'=>now(),
        ],
        [
          'lecture_id'=>3,
          'student_id'=>1,
          'created_at'=>now(),
          'updated_at'=>now(),
        ],
        [
          'lecture_id'=>3,
          'student_id'=>3,
          'created_at'=>now(),
          'updated_at'=>now(),
        ],
        [
          'lecture_id'=>6,
          'student_id'=>2,
          'created_at'=>now(),
          'updated_at'=>now(),
        ],
        [
          'lecture_id'=>5,
          'student_id'=>4,
          'created_at'=>now(),
          'updated_at'=>now(),
        ],
      ]
    );
  }
```




### DatabaseSeeder.phpの変更
DatabaseSeeder.phpに、新しく作成したseederを追加します。

```:database\seeds\DatabaseSeeder.php
public function run()
  {
    $this->call(ClassnamesTableSeeder::class);
    $this->call(SchoolsTableSeeder::class);
    $this->call(StudentsTableSeeder::class);
    $this->call(LecturesTableSeeder::class);
         
    //追加
    $this->call(LectureStudentTableSeeder::class);
}
```






### seederの実行

```:terminal
php artisan db:seed
```
lecture_studentテーブルにレコードが挿入されます。

## リレーションの設定(多対多の場合)
Model同士の関連付けを行います。
LectureとStudentは多対多の関係なので、belongsToManyを使います。

### modelファイルの編集


```:app\Models\Student.php
//追加
//多対多の関係のモデルのメソッド名は複数形にしておきます。
public function lectures(){
  return $this->belongsToMany('App\Models\Lecture');
}
```

```:app\Models\Lecture.php
//追加
//多対多の関係のモデルのメソッド名は複数形にしておきます。
public function students(){
   return $this->belongsToMany('App\Models\Student');
}
```







## リレーションの動作確認

### controllerファイルの編集

```:app\Http\Controllers\StudentController.php
//追加
public function getLecture()
  {
    //生徒IDを指定
    $student_id=1;
 
    //生徒IDから生徒名を取得
    $student_name=student::find($student_id)->name;
 
    //生徒IDから生徒が受講している講義を取得
    $lectures_array=student::find($student_id)->lectures()->get();
    $lectures_name=$lectures_array->implode('name', ',');
 
    return(
      '生徒ID'.$student_id.'の'.$student_name.'が受講している講義は'.$lectures_name.'です。');
  }
```


### ルーティングの追加

- student/lectureにブラウザでアクセスすると、StudentControllerで作成したgetLectureメソッドを実行

```:routes/web.php
Route::get('student/classname', 'StudentController@getClassname');
Route::get('student/school', 'StudentController@getSchool');
  
//追加
Route::get('student/lecture', 'StudentController@getLecture');
```  

### 表示確認

#### 簡易サーバーの起動

```:terminal
php artisan serve
```

#### Webブラウザでアクセスする
http://127.0.0.1:8000/student/lecture



#### 簡易サーバーの停止
terminalでCtrl+Cを押します。





## 補足


### migration

```:terminal
//通常のmigration実行
php artisan migrate

//マイグレーション実行(実行時のプロンプト非表示)
php artisan migrate --force

//全テーブルを削除してから、migrateを実行
php artisan migrate:fresh

//全テーブルを削除してから、migrateとseedを実行
php artisan migrate:fresh --seed

//全マイグレーションをロールバックしてから、migrateを実行
php artisan migrate:refresh

//全マイグレーションをロールバックしてから、migrateとseedを実行
php artisan migrate:refresh --seed

//マイグレーション状況を出力
php artisan migrate:status

//直前に実行したひとまとまりのマイグレーションをロールバック
php artisan migrate:rollback

//最後の5マイグレーションをロールバック
php artisan migrate:rollback --step=5

//すべてのマイグレーションをロールバック
php artisan migrate:reset

``` 
 
### dump-autoload
Vender配下のとあるファイルに全ての*.phpファイルのパスが自動的に記述されます。
マイグレーションがうまく行かないときなどに一度試してみてください。

```:terminal
dump-autoload
```

### seeder

```:terminal
//seeder実行
php artisan db:seed
 
//特定のクラスを指定してseeder実行
php artisan db:seed --class=TestSeeder
```