Laravel入門トップページ


目次

  1. Composerのダウンロードとインストール
  2. コメント掲示板を作成してみよう
  3. リレーションシップを使いこなそう
    1. 概要
    2. Laravelプロジェクトの作成と初期設定
    3. 一対多のリレーションシップ
    4. 多対多のリレーションシップ
    5. ビューを使った表示
    6. 学部の情報を表示・変更する
    7. キャンパスの情報を表示・変更・削除する
    8. 学生の情報を表示・変更・削除する
  4. ユーザ認証の機能を実現しよう
  5. マルチ認証の機能を実現しよう
  6. MongoDB に接続しよう
  7. キューを利用しよう
  8. コマンド(コンソール)を利用しよう
  9. 本番環境にデプロイしよう

リレーションシップを使いこなそう

一対多のリレーションシップ

目次に戻る

概要

「キャンパス」と「学部」の関係は「一対多」である.

campus_faculty

目次に戻る

テーブルの作成

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 で確認してみる

シーダーでデータの投入ができたので,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>
relationship-1

うまく表示できたら 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>
relationship-2

うまく表示できたら 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>
relationship-3

少々見にくいが /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]$

目次に戻る