laravel
docker
docker-compose

[Laravel]チャット作成記(未完成):テーブルの作成

こんにちは。クリスマスまでにチャットアプリを作っていきたいと思います。
Laravelを使っていきます。よろしくお願いします。
ちなみにクリスマスは一人で鍋を食べながらゲーム(ゼノブレイド2)をする予定です。

完成予定図

チャットアプリの完成図としては
1.ユーザーのログイン機能(userテーブル)
2.ユーザーがグループを作れる。(groupテーブル)
3.メッセージの送信(chatテーブル)
4.非同期通信(出来れば)
を予定しています。

開発環境構築

まず初めにこちらの方↓の記事を参考にしながらdockerで開発環境の構築をしてきましょう。
Dockerでlaravelの開発環境構築をしてみた (php-pfm,nginx, mysql)
https://qiita.com/mytv1/items/f26cd77f2801357dee8f
おそらく手順通りにやれば大した時間はかからないはずです。
ただ少し嵌った箇所として

cp .env.example .env

の作業の際に、そのままの.env.example をコピーしたままの.envでやっているとテーブルに保存ができませんでした。
ですので

.env
DB_CONNECTION=mysql
DB_HOST=database
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret

といった感じでDB_HOSTを127.0.0.1からコンテナ名のdatabaseに変更しました。ボクの場合はこれでいけました。

リレーション

userは色々なgroupに入れたほうがいいです。
groupは複数のuserを登録出来た方がいいですね。
ということで userテーブルとgroupテーブルは多対多の関係になると思います。

なので必要なテーブルは
・usersテーブル
・groupsテーブル
・chatsテーブル
・user_group(中間テーブル)
の4つになると思います。多分。

テーブル作成

ではテーブルを作っていきます。

php artisan make:migration ファイル名

というコマンドでマイグレーションファイルを作成します。

例としてgroupテーブルを作っていきます。

groupsテーブルを作りたければ

php artisan make:migration create_groups_table

のコマンドになります。

そして出来るマイグレーションファイルがこちらになります。

2017_12_02_050009_create_group_table.php
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateGroupsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
      \\
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
       \\
    }
}

必要なカラムを考え、記述していきます。

upメソッドにはテーブルを生成するための処理を記述します。
downメソッドにはテーブルを削除するための処理を記述します。

2017_12_02_050009_create_group_table.php
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateGroupsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('groups', function(Blueprint $table){
            $table->increments('id');
            $table->string('name');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
}
Schema::create('users', function (Blueprint $table) {
  ・・・テーブルの作成処理・・・
});

テーブルの作成は、Schemaクラスのcreateメソッドを使って行います。
createは、第一引数にテーブル名、第二引数にはテーブルを作成するための処理をまとめたクロージャーが用意されます。
クロージャー内でカラム名などを設定します。
$table->string('カラム名');
で設定できます。

テーブルの削除は

Schema::drop(カラム名);

で行います。

そして必要なカラムを記述したらマイグレーションを実行します。

php artisan migrate

命名規則は大事

命名規則なんて破っても別に大した影響ないやろ・・・と思ってたら普通にエラーが出ました。
テーブルを実行する際に僕は最初、groupsテーブルではなく、groupテーブルと記述していました。
すると、
'homestead(データベース名).groups'がない
というエラーが出てきてまた少し嵌ってしまいました。
ちゃんと命名規則に乗っ取りテーブルを複数形にしたら直りました。
これを見て正しい命名をしましょう
http://laraweb.net/knowledge/942/

groupテーブルに続いて、chatテーブル、userテーブルも同じように作っていきましょう。

中間テーブルの作成

多対多のリレーションを作るにあたって中間テーブルが必要になってきます。

そもそも中間テーブルとは?
→中間テーブルとは, テーブルと他のテーブルを関連付けるテーブルです。

なので、usersテーブルとgroupsテーブルを多対多の関係で結びたい場合は中間テーブル"user_group"を作らないといけません。
作る手順としては普通のテーブルと変わりません。
しかしカラムが少し先程のgroupテーブルなどとは違ってきます。

2017_12_02_052931_create_user_group_table.php
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateUserGroupTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('user_group', function(Blueprint $table)
        {
            $table->primary('id');
            $table->integer('user_id')->unsigned()->index();
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
            $table->integer('group_id')->unsigned()->index();
            $table->foreign('group_id')->references('id')->on('groups')->onDelete('cascade');

            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('user_group');
    }
}

中間テーブルでは関連付ける二つのテーブルのidを持つ必要があります。
今回関連付けるのはusersとgroupsなので
・user_id
・group_id
を用意しなければなりません。
なので上記のような構成になりました。

$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('group_id')->references('id')->on('groups')->onDelete('cascade');

ちなみにこれは外部キー制約をつけています。この制約をつけることによって親テーブルがない場合はエラーがでるようになります。

あとはマイグレーションファイルを実行すれば中間テーブルは作成できます。

参考URL

https://qiita.com/mytv1/items/f26cd77f2801357dee8f
http://laraweb.net/knowledge/942/
http://kengotakimoto.com/post-2383/
https://readouble.com/laravel/5.3/ja/migrations.html
https://qiita.com/Yorinton/items/3dbf6ad30358bd80fcb0

参考文献

"PHPフレームワーク Laravel入門"
著:掌田津耶乃