「キャンパス」と「学部」の関係は「一対多」である.
campuses と faculties というテーブルを作成するためのマイグレーションファイルを生成する.
[GakuinHana@rin06 laravelRelationship]$ pwd ⏎ /home/GakuinHana/Documents/laravel/laravelRelationship [GakuinHana@rin06 laravelRelationship]$ php artisan make:migration create_campuses_table --create=campuses ⏎ Created Migration: 2018_06_14_051009_create_campuses_table [GakuinHana@rin06 laravelRelationship]$ php artisan make:migration create_faculties_table --create=faculties ⏎ Created Migration: 2018_06_14_051058_create_faculties_table [GakuinHana@rin06 laravelRelationship]$
まず,campuses テーブル作成のためのマイグレーションファイル(database/migrations/yyyy-mm-dd_hhmmss_create_campuses_table.php)を編集する.
database/migrations/yyyy-mm-dd_hhmmss_create_campuses_table.php (抜粋)
public function up()
{
Schema::create('campuses', function (Blueprint $table) {
$table->increments('id');
$table->string('campus', 100);
$table->timestamps();
});
}
次に,faculties テーブル作成のためのマイグレーションファイル(database/migrations/yyyy-mm-dd_hhmmss_create_faculties_table.php)を編集する.ここで,campus_id は外部キーであるので,9-12行目でリレーションシップを設定する.なお onDelete('cascade')
はカスケード削除,つまり連鎖削除を行うオプションである.このオプションを設定すると,例えば,campuses テーブルで KPC のデータが削除されると,faculties テーブルの法学部,薬学部などのデータが連鎖的に削除されることになる.
database/migrations/yyyy-mm-dd_hhmmss_create_faculties_table.php (抜粋)
public function up()
{
Schema::create('faculties', function (Blueprint $table) {
$table->increments('id');
$table->string('faculty', 100);
$table->integer('established')->unsigned();
$table->integer('campus_id')->unsigned();
$table->timestamps();
$table->foreign('campus_id')
->references('id')
->on('campuses')
->onDelete('cascade');
});
}
マイグレーションファイルの編集が終われば,マイグレーションを実行して,テーブルを作成しよう.なお,最初にユーザ管理とパスワードリセットのマイグレーションファイルも生成されているが,今回は使わないので先に削除しておいて問題ない.
[GakuinHana@rin06 laravelRelationship]$ pwd ⏎ /home/GakuinHana/Documents/laravel/laravelRelationship [GakuinHana@rin06 laravelRelationship]$ cd database/migrations/ ⏎ [GakuinHana@rin06 migrations]$ ls ⏎ 2014_10_12_000000_create_users_table.php 2014_10_12_100000_create_password_resets_table.php 2018_06_14_051009_create_campuses_table.php 2018_06_14_051058_create_faculties_table.php [GakuinHana@rin06 migrations]$ rm 2014_10_12_000000_create_users_table.php ⏎ [GakuinHana@rin06 migrations]$ rm 2014_10_12_100000_create_password_resets_table.php ⏎ [GakuinHana@rin06 migrations]$ ls ⏎ 2018_06_14_051009_create_campuses_table.php 2018_06_14_051058_create_faculties_table.php [GakuinHana@rin06 migrations]$ cd ../../ ⏎ [GakuinHana@rin06 laravelRelationship]$ pwd ⏎ /home/GakuinHana/Documents/laravel/laravelRelationship [GakuinHana@rin06 laravelRelationship]$ php artisan migrate ⏎ Migrating: 2018_06_14_051009_create_campuses_table Migrated: 2018_06_14_051009_create_campuses_table Migrating: 2018_06_14_051058_create_faculties_table Migrated: 2018_06_14_051058_create_faculties_table [GakuinHana@rin06 laravelRelationship]$
Git にコミットしておこう.なお,ファイルを削除したら,Git の管理対象からも削除すると良い.このときは git rm ファイル名
として,コミットする.
[GakuinHana@rin06 laravelRelationship]$ git status ⏎ # On branch master # Changes not staged for commit: # (use "git add/rm <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # deleted: database/migrations/2014_10_12_000000_create_users_table.php # deleted: database/migrations/2014_10_12_100000_create_password_resets_table.php # # Untracked files: # (use "git add <file>..." to include in what will be committed) # # database/migrations/2018_06_14_051009_create_campuses_table.php # database/migrations/2018_06_14_051058_create_faculties_table.php no changes added to commit (use "git add" and/or "git commit -a") [GakuinHana@rin06 laravelRelationship]$ git add . ⏎ warning: You ran 'git add' with neither '-A (--all)' or '--ignore-removal', whose behaviour will change in Git 2.0 with respect to paths you removed. Paths like 'database/migrations/2014_10_12_000000_create_users_table.php' that are removed from your working tree are ignored with this version of Git. * 'git add --ignore-removal <pathspec>', which is the current default, ignores paths you removed from your working tree. * 'git add --all <pathspec>' will let you also record the removals. Run 'git status' to check the paths you removed from your working tree. [GakuinHana@rin06 laravelRelationship]$ git status ⏎ # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # new file: database/migrations/2018_06_14_051009_create_campuses_table.php # new file: database/migrations/2018_06_14_051058_create_faculties_table.php # # Changes not staged for commit: # (use "git add/rm <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # deleted: database/migrations/2014_10_12_000000_create_users_table.php # deleted: database/migrations/2014_10_12_100000_create_password_resets_table.php # [GakuinHana@rin06 laravelRelationship]$ git rm database/migrations/2014_10_12_* ⏎ rm 'database/migrations/2014_10_12_000000_create_users_table.php' rm 'database/migrations/2014_10_12_100000_create_password_resets_table.php' [GakuinHana@rin06 laravelRelationship]$ git status ⏎ # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # deleted: database/migrations/2014_10_12_100000_create_password_resets_table.php # renamed: database/migrations/2014_10_12_000000_create_users_table.php -> database/migrations/2018_06_14_051009_create_campuses_table.php # new file: database/migrations/2018_06_14_051058_create_faculties_table.php # [GakuinHana@rin06 laravelRelationship]$ git commit -m'マイグレーション' ⏎ [master a3bb7ab] マイグレーション 3 files changed, 42 insertions(+), 40 deletions(-) delete mode 100644 database/migrations/2014_10_12_100000_create_password_resets_table.php rename database/migrations/{2014_10_12_000000_create_users_table.php => 2018_06_14_051009_create_campuses_table.php} (54%) mode change 100644 => 100755 create mode 100755 database/migrations/2018_06_14_051058_create_faculties_table.php [GakuinHana@rin06 laravelRelationship]$ git log --oneline ⏎ a3bb7ab マイグレーション e991b11 config/app.phpの設定 3fa9439 initial commit [GakuinHana@rin06 laravelRelationship]$
まずはシーダーを生成する.
[GakuinHana@rin06 laravelRelationship]$ php artisan make:seeder CampusesTableSeeder ⏎ Seeder created successfully. [GakuinHana@rin06 laravelRelationship]$ php artisan make:seeder FacultiesTableSeeder ⏎ Seeder created successfully. [GakuinHana@rin06 laravelRelationship]$
次に,キャンパステーブルと学部テーブルにテスト用のデータを記述する.また,database/seeds/DatabaseSeeder.php には2つのシーダーを実行するためのコードを記述する.
database/seeds/CampusesTableSeeder.php (抜粋)
public function run()
{
// 一旦中身を削除する
DB::table('campuses')->delete();
DB::table('campuses')->insert([
'campus' => 'KAC'
]);
DB::table('campuses')->insert([
'campus' => 'KPC'
]);
}
database/seeds/FacultiesTableSeeder.php (抜粋)
public function run()
{
// 一旦中身を削除する
DB::table('faculties')->delete();
DB::table('faculties')->insert([
'faculty' => '栄養学部',
'established' => 1966,
'campus_id' => 1
]);
DB::table('faculties')->insert([
'faculty' => '法学部',
'established' => 1967,
'campus_id' => 2
]);
DB::table('faculties')->insert([
'faculty' => '経済学部',
'established' => 1967,
'campus_id' => 1
]);
DB::table('faculties')->insert([
'faculty' => '薬学部',
'established' => 1972,
'campus_id' => 2
]);
DB::table('faculties')->insert([
'faculty' => '人文学部',
'established' => 2004,
'campus_id' => 1
]);
DB::table('faculties')->insert([
'faculty' => '経営学部',
'established' => 2004,
'campus_id' => 2
]);
DB::table('faculties')->insert([
'faculty' => '総合リハビリテーション学部',
'established' => 2005,
'campus_id' => 1
]);
DB::table('faculties')->insert([
'faculty' => '現代社会学部',
'established' => 2014,
'campus_id' => 2
]);
DB::table('faculties')->insert([
'faculty' => 'グローバル・コミュニケーション学部',
'established' => 2015,
'campus_id' => 2
]);
DB::table('faculties')->insert([
'faculty' => '心理学部',
'established' => 2018,
'campus_id' => 1
]);
}
database/seeds/DatabaseSeeder.php (抜粋)
public function run()
{
$this->call(CampusesTableSeeder::class);
$this->call(FacultiesTableSeeder::class);
}
シーダーの準備ができたら,シーダーを実行しよう.なお,初めてシーダーを実行するときにはClass CampusesTableSeeder does not exist
のようなエラーが表示されることがある.このような場合はphp ../composer.phar dump-autoload
を実行してから,再度シーダを実行する.
[GakuinHana@rin06 laravelRelationship]$ php artisan db:seed ⏎ Seeding: CampusesTableSeeder Seeding: FacultiesTableSeeder [GakuinHana@rin06 laravelRelationship]$
シーダーでデータの投入ができたので,sqlite3 で確認してみよう.
[GakuinHana@rin06 laravelRelationship]$ cd database ⏎ [GakuinHana@rin06 database]$ ls ⏎ database.sqlite factories migrations seeds [GakuinHana@rin06 database]$ sqlite3 database.sqlite ⏎ SQLite version 3.7.17 2013-05-20 00:56:22 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> select * from campuses; ⏎ 1|KAC|| 2|KPC|| sqlite> select * from faculties order by established desc; ⏎ 10|心理学部|2018|1|| 9|グローバル・コミュニケーション学部|2015|2|| 8|現代社会学部|2014|2|| 7|総合リハビリテーション学部|2005|1|| 5|人文学部|2004|1|| 6|経営学部|2004|2|| 4|薬学部|1972|2|| 2|法学部|1967|2|| 3|経済学部|1967|1|| 1|栄養学部|1966|1|| sqlite> select faculties.id, faculties.faculty, campuses.campus ⏎ ...> from faculties inner join campuses ⏎ ...> on faculties.campus_id = campuses.id; ⏎ 1|栄養学部|KAC 2|法学部|KPC 3|経済学部|KAC 4|薬学部|KPC 5|人文学部|KAC 6|経営学部|KPC 7|総合リハビリテーション学部|KAC 8|現代社会学部|KPC 9|グローバル・コミュニケーション学部|KPC 10|心理学部|KAC sqlite> .exit ⏎ [GakuinHana@rin06 database]$ cd .. ⏎ [GakuinHana@rin06 laravelRelationship]$
問題なければ,Gitでコミットしておこう.
Campus モデルと Faculty モデルを作成しよう.なおテーブル名は小文字の複数形であったが,モデルは先頭大文字単数形にしておくことに注意する.
[GakuinHana@rin06 laravelRelationship]$ pwd ⏎ /home/GakuinHana/Documents/laravel/laravelRelationship [GakuinHana@rin06 laravelRelationship]$ ls app/ ⏎ Console Exceptions Http Providers User.php [GakuinHana@rin06 laravelRelationship]$ php artisan make:model Campus ⏎ Model created successfully. [GakuinHana@rin06 laravelRelationship]$ php artisan make:model Faculty ⏎ Model created successfully. [GakuinHana@rin06 laravelRelationship]$ ls app/ ⏎ Campus.php Console Exceptions Faculty.php Http Providers User.php [GakuinHana@rin06 laravelRelationship]$
Git でコミットしておこう.
CampusesController と FacultiesController を作成してコミットしておこう.
[GakuinHana@rin06 laravelRelationship]$ ls app/Http/Controllers/ ⏎ Auth Controller.php [GakuinHana@rin06 laravelRelationship]$ php artisan make:controller CampusesController ⏎ Controller created successfully. [GakuinHana@rin06 laravelRelationship]$ php artisan make:controller FacultiesController ⏎ Controller created successfully. [GakuinHana@rin06 laravelRelationship]$ ls app/Http/Controllers/ ⏎ Auth CampusesController.php Controller.php FacultiesController.php [GakuinHana@rin06 laravelRelationship]$ git add . ⏎ [GakuinHana@rin06 laravelRelationship]$ git commit -m'コントローラの生成' ⏎ [master b2e2949] コントローラの生成 2 files changed, 20 insertions(+) create mode 100644 app/Http/Controllers/CampusesController.php create mode 100644 app/Http/Controllers/FacultiesController.php [GakuinHana@rin06 laravelRelationship]$ git log --oneline ⏎ b2e2949 コントローラの生成 2be5ef0 モデルの生成 eb0b417 シーダーの設定 a3bb7ab マイグレーション e991b11 config/app.phpの設定 3fa9439 initial commit [GakuinHana@rin06 laravelRelationship]$
app/Http/Controllers/ 以下の CampusesController.php と FacultiesController.php に一覧表示の雛形を作成する.
app/Http/Controllers/CampusesController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class CampusesController extends Controller
{
public function index()
{
dd("キャンパス一覧");
}
}
app/Http/Controllers/FacultiesController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class FacultiesController extends Controller
{
public function index()
{
dd("学部一覧");
}
}
次に,ルートの定義を確認する.現状はトップページ / (とapi/user)だけである.
[GakuinHana@rin06 laravelRelationship]$ php artisan route:list ⏎ +--------+----------+----------+------+---------+--------------+ | Domain | Method | URI | Name | Action | Middleware | +--------+----------+----------+------+---------+--------------+ | | GET|HEAD | / | | Closure | web | | | GET|HEAD | api/user | | Closure | api,auth:api | +--------+----------+----------+------+---------+--------------+ [GakuinHana@rin06 laravelRelationship]$
/campuses と /faculties の URI が指定されたときに,それぞれのコントローラの index 関数が呼び出されるように routes/web.php を編集する.
routes/web.php (抜粋)
Route::get('/', function () {
return view('welcome');
});
Route::get('/campuses', 'CampusesController@index');
Route::get('/faculties', 'FacultiesController@index');
再度,ルートの定義を確認する.
[GakuinHana@rin06 laravelRelationship]$ php artisan route:list ⏎ +--------+----------+-----------+------+------------------------------------------------+--------------+ | Domain | Method | URI | Name | Action | Middleware | +--------+----------+-----------+------+------------------------------------------------+--------------+ | | GET|HEAD | / | | Closure | web | | | GET|HEAD | api/user | | Closure | api,auth:api | | | GET|HEAD | campuses | | App\Http\Controllers\CampusesController@index | web | | | GET|HEAD | faculties | | App\Http\Controllers\FacultiesController@index | web | +--------+----------+-----------+------+------------------------------------------------+--------------+
Webサーバを起動して,実際に /campuses と /faculties にアクセスしてみよう.
[GakuinHana@rin06 laravelRelationship]$ php artisan serve --host=rin06.ba.kobegakuin.ac.jp --port 8385 ⏎ Laravel development server started: <http://rin06.ba.kobegakuin.ac.jp:8385>
うまく表示できたら Git でコミットしておこう.
まだ,リレーションシップができていないが,とりあえずデータベースから一覧を取得してみよう.CampusesController と FacultiesController の index をそれぞれ変更する.
app/Http/Controllers/CampusesController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Campus; // <<<<<<------- 追加
class CampusesController extends Controller
{
public function index()
{
$campuses = Campus::get();
dd($campuses);
}
}
app/Http/Controllers/FacultiesController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Faculty; // <<<<<<------- 追加
class FacultiesController extends Controller
{
public function index()
{
$faculties = Faculty::get();
dd($faculties);
}
}
Webサーバを起動して,実際に /campuses と /faculties にアクセスしてみよう.すべてのデータを取得できていることを確認する.しかし,まだ法学部のキャンパスid が 2であるが,それがKACであるという関連(リレーションシップ)はまだはっきりしない(取得できていない)ことにも注意しよう.
[GakuinHana@rin06 laravelRelationship]$ php artisan serve --host=rin06.ba.kobegakuin.ac.jp --port 8385 ⏎ Laravel development server started: <http://rin06.ba.kobegakuin.ac.jp:8385>
うまく表示できたら Git でコミットしておこう.
ようやくリレーションシップを設定する準備ができた.学部が所属できるキャンパスは1つ,キャンパスには複数の学部が所属しているので,「キャンパスと学部は一対多」である.Laravel ではモデルの中にリレーションシップを定義する.具体的には,一側(Campus)では,多側(faculties)を取得するメソッドを記述する.一方で,多側(Faculty)では,一側(campus)を取得するメソッドを記述する.それぞれ,複数形,単数形の違いに注意すること. app/Campus.php と app/Faculty.php にそれぞれ 所属する学部(複数), 所属キャンパス(単数)を取得するためのメソッドを記述する.
app/Campus.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Campus extends Model
{
// One to Many の One 側
public function faculties()
{
return $this->hasMany('App\Faculty');
}
}
app/Faculty.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Faculty extends Model
{
// One to Many の Many 側
public function campus()
{
return $this->belongsTo('App\Campus');
}
}
上記のコードのように,一側のキャンパスモデルでは,学部が複数あるので,faculties()
メソッドを準備し,hasMany()
によって学部を取得するように設定する.多側の学部モデルでは,所属キャンパスはひとつであることから,campus()
メソッドを準備し,belongsTo()
によってキャンパスを取得するように設定する.
モデルにメソッドを記述できたら,コントローラから呼び出してみよう.
app/Http/Controllers/CampusesController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Campus;
class CampusesController extends Controller
{
public function index()
{
$campuses = Campus::get();
foreach ($campuses as $campus) {
$faculties = $campus->faculties;
var_dump("----------");
var_dump($campus->campus);
foreach ($faculties as $faculty) {
$str = $faculty->faculty . " : " . $faculty->established;
var_dump($str);
}
}
}
}
app/Http/Controllers/FacultiesController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Faculty;
class FacultiesController extends Controller
{
public function index()
{
$faculties = Faculty::get();
foreach ($faculties as $faculty) {
$str = $faculty->faculty . " : " . $faculty->campus->campus;
var_dump($str);
}
}
}
Webサーバを起動して,実際に /campuses と /faculties にアクセスしてみよう.
[GakuinHana@rin06 laravelRelationship]$ php artisan serve --host=rin06.ba.kobegakuin.ac.jp --port 8385 ⏎ Laravel development server started: <http://rin06.ba.kobegakuin.ac.jp:8385>
少々見にくいが /campuses では 2つのキャンパスを取り出し,それぞれのキャンパスに所属する学部の一覧と設置年度を取得することができている.また /faculties では 10個の学部を取り出し,それぞれの所属キャンパスを取得できていることがわかる.
うまく表示できたら Git でコミットしておこう.
[GakuinHana@rin06 laravelRelationship]$ git log --oneline ⏎ 8c0f747 モデルでリレーションシップ 6ee34cd データベースから一覧を取得 4b66173 一覧表示の雛形とルート b2e2949 コントローラの生成 2be5ef0 モデルの生成 eb0b417 シーダーの設定 a3bb7ab マイグレーション e991b11 config/app.phpの設定 3fa9439 initial commit [GakuinHana@rin06 laravelRelationship]$