しぐれがき

これまで挑戦したことの備忘録!!

【投稿アプリ自作(4)】テーブル設計とマイグレーション実行(Laravel)

f:id:shiguregaki:20170708104151j:plain
Webアプリを自作するためにPHPフレームワークのLaravelを導入することに決めました。
PHP初心者かつLaravel初心者ですが、自分なりにスキルを得るためにLaravelを用いた記事投稿アプリを自作しました。その過程を備忘録としてまとめます。
最終的にはブラウザを利用して記事投稿画面の表示、ユーザごとの記事投稿数のグラフ化を目指したいと思います。
本記事は連載【投稿アプリ自作】の第四回目で、投稿アプリのテーブル設計に基づいてマイグレーションファイルを作成し、実行することで、投稿アプリに使用するテーブルの生成をする過程をまとめます。
※:Laravelは5.3からファイル構成が大幅に変わりました。本記事ではLaravel5.3以降を使って説明したいと思います。
※2:データベースはXAMPPに入っていたMySQLを使うことにします。事前にデータベースアカウントを登録しておいてください。

目次

ゴール

本記事では、以下の2つを目指します。
・テーブル設計に基づいてマイグレーションファイルを作成する
マイグレーションを実行することで、投稿アプリに使用する新規テーブルを作成する

f:id:shiguregaki:20170708104204j:plain

必要なもの

必要なもの 価格(円)
1 PC ピンキリ
備考 インターネット接続可能なこと
2 XAMPP 無料
備考 持っていない場合は、こちらを参照→XAMPPのインストール方法
3 Composer 無料
備考 持っていない場合は、こちらを参照→Composerのインストール方法
4 Laravelフレームワーク 無料
備考 インストールしていない場合は、こちらを参照→Laravelのインストール方法
5 MySQLのデータベースアカウント 無料
備考 持っていない場合は、こちらを参照→phpMyAdminでデータベースとユーザを新規登録する




事前準備

XAMPPでApacheMySQLを起動!

データベースの設定をするために、ApacheMySQLを起動します。

f:id:shiguregaki:20170708104219j:plain



データベースの準備

データベースにアクセスるため、MySQLのデータベースおよびユーザを新規作成します。
以下にphpMyAdminを使ってMySQLのデータベース、ユーザを新規作成する方法をまとめました。
ご参考にしてください。

http://ysktec.com/shiguregaki/blog/?p=1135shiguregaki.hatenablog.com





テーブル設計

この章では投稿アプリに使用するテーブルを定義します。
テーブルは以下の5つのテーブルを作成することにします。
・Articlesテーブル
・DetailedArticlesテーブル
・Articlesテーブル
・Categoriesテーブル
・Tagsテーブル



テーブルの構成

Articlesテーブル
記事を管理するテーブルです。各記事はユーザやカテゴリー、タグを紐づけられています。

カラム名 変数名 補足
記事ID article_id 主キー
ユーザID user_id 外部キー
ユーザごとの記事ID user_article_id
カテゴリーID category_id 外部キー
タグID tag_id 外部キー

DetailedArticlesテーブル
記事詳細を管理するテーブルです。Articlesテーブルとarticle_idで1:1に関連を持っています。

カラム名 変数名 補足
記事ID article_id 主キー 外部キー
タイトル title
記事内容 body
投稿日 published_date

ArticleUsersテーブル
記事を書くユーザを管理するテーブルです。Articlesテーブルとuser_idで1:多に関連を持っています。

カラム名 変数名 補足
ユーザID user_id 主キー
ユーザ名 user_name
パスワード password
性別 gender
メールアドレス mail_address

Categoryテーブル
記事のカテゴリーを管理するテーブルです。Articlesテーブルとcategory_idで1:多に関連を持っています。

カラム名 変数名 補足
カテゴリーID category_id 主キー
カテゴリー名 category_name

Tagsテーブル
記事のタグを管理するテーブルです。Articlesテーブルとtag_idで1:多に関連を持っています。

カラム名 変数名 補足
タグID tag_id 主キー
タグ名 tag_name


テーブルの関連性

上記のテーブルの関連性をER図にまとめると下の様になります。(IDEDF1X記法で記述)
※ネットで検索しながら見よう見まねで書いたので間違っているかもしれませんがご容赦ください。

f:id:shiguregaki:20170708104239j:plain





Laravelソースファイルの変更

変更や新規作成するLaravelファイル一覧

Laravelのプロジェクトファイル配下にあるファイルで本記事の中で変更、新規作成するファイルについてまとめました。

ファイル名 対応 備考
1
database/migrations/xxxx_xx_xx_xxxxx_
create_articles_table.php
新規作成 php artisan make:model <モデル名> -m”コマンドで新規作成(後述)
2 app/Article.php 新規作成 同上
3
database/migrations/xxxx_xx_xx_xxxxx_
create_detailed_articles_table.php
新規作成 同上
4 app/Detailed_Article.php 新規作成 同上
5
database/migrations/xxxx_xx_xx_xxxxx_
create_article_users_table.php
新規作成 同上
6 app/Article_User.php 新規作成 同上
7
database/migrations/xxxx_xx_xx_xxxxx_
create_categories_table.php
新規作成 同上
8 app/Category.php 新規作成 同上
9
database/migrations/xxxx_xx_xx_xxxxx_
create_tags_table.php
新規作成 同上
10 app/Tag.php 新規作成 同上




モデルファイルとマイグレーションファイルの新規作成

データベースを作成するためにモデルファイルとマイグレーションファイルを作成します。
モデルファイルとはデータベースのカラムの設定やデータベースから得た情報の操作を行うことができるファイルになります。
マイグレーションファイルはデータベースに対してテーブル作成やカラム追加などの操作を行うことができるファイルになります。
それぞれのファイルはartisanコマンドを使って作成します。

以下のコマンドを使って、モデルファイルとマイグレーションファイルを新規作成します。


 モデルファイルとマイグレーションファイルを作成するコマンド 
>php artisan make:model <モデルファイル名> -m

  • mオプションがモデルファイルと同時にマイグレーションファイルを作成するオプションになります。





注意:
このコマンドを実行した順番でマイグレーションファイルが実行されるため、このコマンドを実行する順番を考慮する必要があります。
これはマイグレーションファイルで指定するテーブル間の外部キー制約が原因で、作成されるテーブルの順番を考えないと制約に違反してエラーとなってしまうためです。

テーブルの関連性の章で示した通り、各テーブル間は外部キーで関連をもっています。
ArticlesテーブルはArticleUsersテーブル、Categoriesテーブル、Tagsテーブルと外部キーで関連づいています。
DetailedArticlesテーブルはArticlesテーブルと外部キーで関連づいています。
ですので、上記コマンドでモデルファイルを実行する順番は

ArticleUsersテーブル、Categoriesテーブル、Tagsテーブル => Articlesテーブル => DetailedArticlesテーブル

という順番になります。





下の画像の様にArticleUserモデル、Categoryモデル、Tagモデル、Articleモデル、DetailedArticleモデルを順に新規作成します。
※モデルは単数表記で記載するのが慣例のようです。

f:id:shiguregaki:20170708104256j:plain

モデルの作成と同時に自動でマイグレーションファイルが作成されています。
xxxx_xx_xx_xxxxx_create_article_users_table
xxxx_xx_xx_xxxxx_create_categories_table
xxxx_xx_xx_xxxxx_create_tags_table
xxxx_xx_xx_xxxxx_create_articles_table
xxxx_xx_xx_xxxxx_create_detailed_articles_table





正常にモデルファイル、マイグレーションファイルが作成されると以下のディレクトリにコマンドで指定した名称でファイルができているはずです。


モデルファイル格納ディレクト
<プロジェクトファイルのルートディレクトリ>/app/

f:id:shiguregaki:20170708104306j:plain







マイグレーションファイル格納ディレクト
<プロジェクトファイルのルートディレクトリ>/database/migrations/

f:id:shiguregaki:20170708104317j:plain




ArticleUsersテーブルのマイグレーションファイルの変更

テーブル設計の章で設計した内容に基づいてArticleUsersテーブルのマイグレーションファイルを設定していきます。
以下のソースでは主キーにuser_idを指定し、その他のカラムも型に応じて設定しています。

<?php

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

class CreateArticleUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('article_users', function (Blueprint $table) {
            //ユーザIDの設定(主キー)
            $table->increments('user_id');
            //ユーザ名の設定
            $table->string('user_name');
            //パスワードの設定
            $table->string('password');
            //性別の設定
            $table->string('gender');
            //メールアドレスの設定
            $table->string('mail_address');
            //NULL値可能なcreated_atとupdated_atカラム追加
            $table->timestamps();
        });
    }

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


up()はマイグレーションを実行したときにコールされる関数です。
down()はマイグレーションが失敗時に実行される関数です。




Categoriesテーブルのマイグレーションファイルの変更

テーブル設計の章で設計した内容に基づいてCategoriesテーブルのマイグレーションファイルを設定していきます。
以下のソースでは主キーにcategory_idを指定し、その他のカラムも型に応じて設定しています。

<?php

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

class CreateCategoriesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('categories', function (Blueprint $table) {
            //カテゴリーIDの設定(主キー)
            $table->increments('category_id');
            //カテゴリー名の設定
            $table->string('category_name');
            //NULL値可能なcreated_atとupdated_atカラム追加
            $table->timestamps();
        });
    }

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





Tagsテーブルのマイグレーションファイルの変更

テーブル設計の章で設計した内容に基づいてTagsテーブルのマイグレーションファイルを設定していきます。
以下のソースでは主キーにtag_idを指定し、その他のカラムも型に応じて設定しています。

<?php

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

class CreateTagsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tags', function (Blueprint $table) {
            //タグIDの設定(主キー)
            $table->increments('tag_id');
            //タグ名の設定
            $table->string('tag_name');
            //NULL値可能なcreated_atとupdated_atカラム追加
            $table->timestamps();
        });
    }

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




Articlesテーブルのマイグレーションファイルの変更

テーブル設計の章で設計した内容に基づいてArticlesテーブルのマイグレーションファイルを設定していきます。
以下のソースでは主キーにarticle_idを指定し、ユーザID、カテゴリーID、タグIDを外部キーとして紐づけています。
その他のカラムも型に応じて設定しています。

<?php

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

class CreateArticlesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('articles', function (Blueprint $table) {
            //記事IDの設定
            $table->increments('article_id');
            //ユーザIDの設定
            $table->integer('user_id')->unsigned();
            //ユーザIDをarticle_usersテーブルの主キーと紐づける
            $table->foreign('user_id')->references('user_id')->on('article_users');
            //ユーザごとの記事IDの設定
            $table->integer('user_article_id')->unsigned();
            //カテゴリーIDの設定
            $table->integer('category_id')->unsigned();
            //カテゴリーIDをcategoriesテーブルの主キーと紐づける
            $table->foreign('category_id')->references('category_id')->on('categories');
            //タグIDの設定
            $table->integer('tag_id')->unsigned();
            //タグIDをcategoriesテーブルの主キーと紐づける
            $table->foreign('tag_id')->references('tag_id')->on('tags');
            //NULL値可能なcreated_atとupdated_atカラム追加
            $table->timestamps();
        });
    }

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




DetailedArticlesテーブルのマイグレーションファイルの変更

テーブル設計の章で設計した内容に基づいてDetailedArticlesテーブルのマイグレーションファイルを設定していきます。
以下のソースではarticle_idをArticlesテーブルの外部キーと紐づけています。
その他のカラムも型に応じて設定しています。

<?php

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

class CreateDetailedArticlesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('detailed_articles', function (Blueprint $table) {
            //サロケードの場合、ここを有効にして複合キーを無効にする
            $table->integer('article_id')->unsigned();
            //記事IDをarticlesテーブルの主キーと紐づける
            $table->foreign('article_id')->references('article_id')->on('articles');
            //タイトルの設定
            $table->string('title');
            //記事内容の設定
            $table->text('body');
            //投稿日の設定
            $table->timestamp('published_date');
            //NULL値可能なcreated_atとupdated_atカラム追加
            $table->timestamps();
        });
    }

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




マイグレーションの実行

マイグレーションを実行するには以下のコマンドをコマンドプロンプト上で実行します。


 マイグレーション実行コマンド 
>php artisan migrate

f:id:shiguregaki:20170708104413j:plain




データベースの確認

データベースが正しく作成されているか確認するため、phpMyAdminにアクセスします。
ブラウザでphpMyAdmin(以下のURL)にアクセスしてください。

phpMyAdminのアクセス先http://localhost/phpmyadmin

以下の5つのテーブルが新規で作成されているはずです。
・articles(Articlesテーブル)
・article_users(ArticleUsersテーブル)
・categories(Categoriesテーブル)
・detatiled_articles(DetatiledArticlesテーブル)
・tags(Tagsテーブル)

※以下の3つのテーブルはlaravelにデフォルトであるテーブルです。
・migrations
・password_resets
・users

f:id:shiguregaki:20170708104423j:plain





ArticleUsersテーブルの確認

テーブル設計の章で設計した以下のカラムができています。
・ユーザid:user_id(主キー)
・ユーザ名:user_name
・パスワード:password
・性別:gender
・メールアドレス:mail_address
※created_at,updated_atはテーブル生成とアップデートした時間でマイグレーションファイルで指定した$table->timestamps();によって作成されているカラムです。

f:id:shiguregaki:20170708104445j:plain




Categoriesテーブルの確認

テーブル設計の章で設計した以下のカラムができています。
・カテゴリーid:category_id(主キー)
・カテゴリー名:category_name
※created_at,updated_atはテーブル生成とアップデートした時間でマイグレーションファイルで指定した$table->timestamps();によって作成されているカラムです。

f:id:shiguregaki:20170708104458j:plain




Tagsテーブルの確認

テーブル設計の章で設計した以下のカラムができています。
・タグid:tag_id(主キー)
・タグ名:tag_name
※created_at,updated_atはテーブル生成とアップデートした時間でマイグレーションファイルで指定した$table->timestamps();によって作成されているカラムです。

f:id:shiguregaki:20170708104506j:plain




Articlesテーブルの確認

テーブル設計の章で設計した以下のカラムができています。
・記事id:article_id(主キー)
・ユーザid:user_id(外部キー)
・ユーザごとの記事id:user_article_id
・カテゴリーid:category_id(外部キー)
・タグid:tag_id(外部キー)
※created_at,updated_atはテーブル生成とアップデートした時間でマイグレーションファイルで指定した$table->timestamps();によって作成されているカラムです。

f:id:shiguregaki:20170708104514j:plain




DetatiledArticlesテーブルの確認

テーブル設計の章で設計した以下のカラムができています。
・記事id:article_id(主キー、外部キー)
・タイトル:title
・記事内容:body
・投稿日:published_date
※created_at,updated_atはテーブル生成とアップデートした時間でマイグレーションファイルで指定した$table->timestamps();によって作成されているカラムです。

f:id:shiguregaki:20170708104522j:plain





まとめ

今回はLaravelを使って以下の2つのことを確認しました。
・テーブル設計に基づいてマイグレーションファイルを作成する
マイグレーションを実行することで、投稿アプリに使用する新規テーブルを作成する

今回は設計に基づいたマイグーレーションを作成し、実行することでテーブルを新規に作成しました。
これによりテーブルの型が決まりました。しかし、実際にアプリからアクセスするにはモデルにも設定が必要です。
次回以降ではモデルの設定をして、実際のデータにアクセスする方法をまとめたいと思います。



次回記事

次回記事はモデルファイルの設定についてまとめたいと思います。

http://shiguregaki.hatenablog.com/entry/p45shiguregaki.hatenablog.com




前回記事

shiguregaki.hatenablog.com


以上!