転職したらスマレジだった件

スマレジのエンジニアやまてのテックブログです。マジレス大歓迎です。

家族ユーザー招待機能 の詳細設計と実装(2) - はじめてのWebアプリ開発を振り返る Part6

こんにちは!

スマレジ・テックファームのWebエンジニアやまてと申します。

はじめに

今回は、Web業界実務未経験での転職活動用にポートフォリオとして作成した『はじめてのWebアプリ開発を振り返る』記事です。


※ 作成したポートフォリオは、絵本を読み聞かせしたことの記録・管理を、家族と共有できるWebアプリケーションです

qiita.com


実装したオリジナルの機能の一つである「家族ユーザー招待」機能について、記事にします。

概要と基本設計

ryamate.hatenablog.com

詳細設計と実装

(1) 家族招待メール送信フォームの作成

(2) マイグレーションファイルからのテーブル作成【今回】

(3) 家族招待メール(テキスト版)の送信処理の作成

(4) 家族招待メール(テキスト版)のテンプレートの作成

(5) ユーザー登録フォームと登録処理の作成

今回は、Laravelのマイグレーション機能を使って、データベースに invites テーブルを作成する手順です。


目次

使用技術、サービスなど

  • フロントエンド
  • バックエンド
    • PHP 7.4.13
    • Laravel 6.20.20
    • MySQL 8.0.23
  • メール関連
    • MailHog(開発者向けのメールテストツール、開発環境)

      github.com

    • SendGrid(メール配信サービス、本番環境)

      sendgrid.kke.co.jp


マイグレーションとは

マイグレーションとは、データベースにテーブルを作成したり、既存のテーブルにカラム(項目)を追加したりといった、データベース内の定義を変更する機能です。

Laravel を使ってデータベースにテーブルを作成するには、まずマイグレーションファイルを作成する必要があります。

readouble.com

家族ユーザー招待に必要なデータを保存するために、Invites テーブルを用意します。

テーブルを必要とする理由は、どの家族(family_id)が、誰(email)を招待したかと、その招待 URL に利用するトークン(token)を保存するためです。

1. マイグレーションファイルの作成

以下のコマンドを実行して、マイグレーションファイルを作成します。

$ php artisan make:migration create_invites_table --create=invites

※ docker-compose コマンドで実行する場合(app コンテナ内)

$ docker-compose exec app php artisan make:migration create_invites_table --create=invites

コマンドを実行すると、backend/database/migrations/ ディレクトリに、以下のファイルが作成される。

  • 作成:backend/database/migrations/2021_06_09_180935_create_invites_table.php
<?php

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

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

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

2. マイグレーションファイルの編集

2-1. テーブル定義の確認

「家族ユーザー招待」機能で利用するテーブルの定義は以下の通りです。

カラム名 データ型 役割・備考
id INTEGER 招待メール発行を管理するID
family_id INTEGER 招待した側のファミリーID
email VARCHAR(255) 招待された側のメールアドレス
token VARCHAR(16) 招待メールのトーク
created_at TIMESTAMP 作成日時
updated_at TIMESTAMP 更新日時

どの家族(family_id)が、誰(email)を招待したかと、その招待 URL に利用するトークン(token)を保存します。

2-2. マイグレーションファイルの編集

作成されたファイルを編集します。

  • 編集:backend/database/migrations/2021_06_09_180935_create_invites_table.php
<?php

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

class CreateInvitesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('invites', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->unsignedBigInteger('family_id');
            $table->string('email');
            $table->string('token', 16)->unique();
            $table->timestamps();

            $table->foreign('family_id')
                ->references('id')
                ->on('families');
        });
    }

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

マイグレーションファイルでカラムを定義するには、 $table->カラムの属性('カラム名'); と記述します。

マイグレーションを実行すると、このマイグレーションファイルが使用され、設定したカラムを持った invites テーブルが作成されます。

2-3. 参考

使用できるカラムタイプ

使用できるさまざまなカラムタイプがある。

コマンド 説明
$table->bigIncrements('id'); 符号なしBIGINTを使用した自動増分ID(主キー)
$table->unsignedBigInteger('votes'); 符号なしBIGINTカラム
$table->string('name', 100); 文字長を指定したVARCHARカラム
$table->timestamps(0); 有効(全体)桁数指定でNULL値可能なcreated_atとupdated_atカラム追加

readouble.com

unique メソッド

uniqueメソッドを使うことで、そのカラムにユニーク制約を付ける。ユニーク制約とは、テーブル内で他のレコードと同じ値を重複させないという制約。

invites テーブルについては、 token を重複させないため、ユニーク制約を追加している。

外部キー制約

family_id については、カラムを作成するだけでなく、外部キー制約を付けている。

$table->foreign('family_id')
    ->references('id')
    ->on('families');

上記は、「 invites テーブルの family_id カラムは、 families テーブルのidカラムを参照すること」という制約になる。

外部キー制約を付けることで、「発行された招待用トークンがどの家族への招待でもない」という状態を作れないようにしている。

3. マイグレーションの実行

以下のコマンドで、マイグレーションを実行します。

$ php artisan migrate

※ docker-compose コマンドで実行する場合(app コンテナ内)

$ docker-compose exec app php artisan migrate

4. テーブルの作成状況の確認

以下コマンドを実行して、テーブルの作成状況を確認します。

$ bash -c 'mysql -u $MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE'

※ docker-compose コマンドで実行する場合(db コンテナ内)

$ docker-compose exec db bash -c 'mysql -u $MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE'
# r_yamate @ mbp in ~/Documents/code/Yonde-app on git:doc/mod_erd x [7:23:52]
$ docker-compose exec db bash -c 'mysql -u $MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE'
mysql: [Warning] Using a password on the command line interface can be insecure.
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.29 MySQL Community Server - GPL

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
mysql> SHOW COLUMNS FROM invites;
+------------+-----------------+------+-----+---------+----------------+
| Field      | Type            | Null | Key | Default | Extra          |
+------------+-----------------+------+-----+---------+----------------+
| id         | bigint unsigned | NO   | PRI | NULL    | auto_increment |
| family_id  | bigint unsigned | NO   | MUL | NULL    |                |
| email      | varchar(255)    | NO   |     | NULL    |                |
| token      | varchar(16)     | NO   | UNI | NULL    |                |
| created_at | timestamp       | YES  |     | NULL    |                |
| updated_at | timestamp       | YES  |     | NULL    |                |
+------------+-----------------+------+-----+---------+----------------+
6 rows in set (0.01 sec)

おわりに

今回の記事は以上です!

次回は、詳細設計と実装のつづき(家族招待メール(テキスト版)の送信処理の作成など)について書きます。

ありがとうございました。

これまでの関連記事

これまでの関連記事です。

ryamate.hatenablog.com

ryamate.hatenablog.com

ryamate.hatenablog.com



ただ結局は、時間の長さではなくやったことの量と質が大事だから、確保した時間の中でどれだけ濃い時間を過ごせるかを大事にしていきたいです。