yps並走備忘録 Task5 簡易Webアプリの作成(SQLとモデルを理解する編)


今回の主な課題

・MySQLのVIEWテーブルの理解
・Bootstrap UIの導入
・Laravel Mixの使い方

事前準備

Node.jsとnpmのアップデート
sudo yum remove node npm -y
curl -sL https://rpm.nodesource.com/setup_12.x | sudo bash -
sudo yum install nodejs -y

インストールで来たら下記コマンドでアップデートされていることを確認
$ node -v 例:v12.18.3
$ npm -v 例:6.14.6

一度Laravelのディレクトリに戻り、Laravel Mix(開発用)でビルドします
cd /var/www/html/yps
rm -rf ./node_modules
npm install && npm run dev

LaravelのuiにBootstrapを指定
composer require laravel/ui
php artisan ui bootstrap

Bootstrapをビルド
npm install && npm run dev

今回使用するデータをMySQLへ
1. VS Code内でターミナルを起動(ctrl+shift+@)
2. pwd ⇒Laravelのプロジェクトフォルダ(/var/www/html/yps)にいることを確認
3. mkdir resources/sql ⇒SQLファイル格納用のディレクトリを作成
4. mysqldump -u root -p -d worldcup2014db > resources/sql/worldcup2014db.sql ⇒テーブルの定義ファイルを取得(データは入手出来ていません)
5. grep -i 'create table' resources/sql/worldcup2014db.sql ⇒テーブルを確認[^1]
6. 各テーブル(countries, goals, pairings, players)にフィールド(expired_at, deleted_at, updated_at, created_at)を追加

5の結果

CREATE TABLE `countries` (
CREATE TABLE `goals` (
CREATE TABLE `goals_tmp` (
CREATE TABLE `pairings` (
CREATE TABLE `pairings_tmp` (
CREATE TABLE `players` (
CREATE TABLE `players_tmp` (

6の参考例

CREATE TABLE `countries` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) DEFAULT NULL,
  `ranking` int(11) DEFAULT NULL,
  `group_name` varchar(1) DEFAULT NULL,
  `expired_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `deleted_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

MySQLでデータベースを削除⇒作り直し
1. mysql -u root -p
2. drop database worldcup2014db;
3. create database worldcup2014db;
4. use worldcup2014db;
5. source resources/sql/worldcup2014db.sql; ⇒ 作ったSQLファイルを元にテーブルを作成
6. show tables; ⇒ テーブルが作成されているか確認
7. OKならexit;でMySQL CLiから出る

Task 3 同様にデータを取得~流し込みの準備
1. cd /tmp
2. sudo yum install wget unzip -y
3. wget http://tech.pjin.jp/wp-content/uploads/2016/04/worldcup2014.zip
4. unzip http://worldcup2014.zip
5. ls -la worldcup2014.sql
6. 各テーブル(countries, goals, goals_tmp, pairings, pairings_tmp, players, players_tmp)のCREATE TABLE ~ DEFAULT CHAESET=utf8;までを削除(↓の部分)

CREATE TABLE `countries` (
  `id` int(11) NOT NULL,
  `name` varchar(50) DEFAULT NULL,
  `ranking` int(11) DEFAULT NULL,
  `group_name` varchar(1) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

**データの流し込み
7. mysql -u root -p -D worldcup2014db
8. source /tmp/worldcup2014.sql; //warningが出ますが特に問題はないそうです
9. 各テーブルのデータ件数をチェックして下記になっていればOK

mysql> select count(*) from countries;
+----------+
| count(*) |
+----------+
|       32 |
+----------+

mysql> select count(*) from goals;
+----------+
| count(*) |
+----------+
|      188 |
+----------+

mysql> select count(*) from pairings;
+----------+
| count(*) |
+----------+
|      144 |
+----------+

mysql> select count(*) from players;
+----------+
| count(*) |
+----------+
|      736 |
+----------+

問題なければexit;でMySQL Cliから出る

簡易アプリケーションの作成

使うデータは用意できたので、今度はデータを使ってアプリケーションを作成してみます。

モデルクラスの作成
Task3で作成したモデルクラスを削除
cd /var/www/html/yps
rm app/Models/Player.php

以下のコマンドを打ってデータベースと連動したモデルクラスを作成します
php artisan make:model Models/Country -m
php artisan make:model Models/Goal -m
php artisan make:model Models/Pairing -m
php artisan make:model Models/Player -m

上記で作成した各モデルクラスに明示的にテーブルを指定し、ついでに$dateも指定します。
※以下はPlayerモデルの例です

Player.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Player extends Model
{
    protected $table = "players";
    protected $dates = ["expired_at", "deleted_at", "updated_at", "created_at"];
}

コントローラークラスの作成
php artisan make:controller CountryController --resource --model=Models/Country
php artisan make:controller GoalController --resource --model=Models/Goal
php artisan make:controller PairingController --resource --model=Models/Pairing
php artisan make:controller PlayerController --resource --model= Models/Player

php artisan make:controller WelcomeController --resource

Viewの作成
resources/views/welcome.blade.phpに以下をコピペ

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <title>yotaro prg</title>

        <!-- Fonts -->
        <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">

        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <meta name="description" content="">
        <meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors">
        <meta name="generator" content="Jekyll v4.1.1">

        <!-- Bootstrap core CSS -->
        <link href="{{ asset('css/app.css') }}" rel="stylesheet">
        <!-- Favicons -->
        <link rel="apple-touch-icon" href="/yotaro.jpg" sizes="180x180">
        <link rel="icon" href="/yotaro.jpg" sizes="32x32" type="image/jpg">
        <link rel="icon" href="/yotaro.jpg" sizes="16x16" type="image/jpg">
        <?php /*
        <link rel="manifest" href="/docs/4.5/assets/img/favicons/manifest.json">
        <link rel="mask-icon" href="/docs/4.5/assets/img/favicons/safari-pinned-tab.svg" color="#563d7c">
        */ ?>
        <link rel="icon" href="/yotaro.jpg">
        <meta name="theme-color" content="#563d7c">
        <style>
            body {
                padding-top: 5rem;
            }
            .starter-template {
                padding: 3rem 1.5rem;
                text-align: center;
            }
            .bd-placeholder-img {
                font-size: 1.125rem;
                text-anchor: middle;
                -webkit-user-select: none;
                -moz-user-select: none;
                -ms-user-select: none;
                user-select: none;
            }
            @media (min-width: 768px) {
                .bd-placeholder-img-lg {
                    font-size: 3.5rem;
                }
            }
        </style>
    </head>
    <body>
        <nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
            <a class="navbar-brand" href="#">Navbar</a>
            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarsExampleDefault">
                <ul class="navbar-nav mr-auto">
                    <li class="nav-item active">
                        <a class="nav-link" href="#">Home 
                            <span class="sr-only">(current)</span>
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#">Link</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
                    </li>
                    <li class="nav-item dropdown">
                        <a class="nav-link dropdown-toggle" href="#" id="dropdown01" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a>
                        <div class="dropdown-menu" aria-labelledby="dropdown01">
                            <a class="dropdown-item" href="#">Action</a>
                            <a class="dropdown-item" href="#">Another action</a>
                            <a class="dropdown-item" href="#">Something else here</a>
                        </div>
                    </li>
                </ul>
                <form class="form-inline my-2 my-lg-0">
                    <input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">
                    <button class="btn btn-secondary my-2 my-sm-0" type="submit">Search</button>
                </form>
            </div>
        </nav>
        <main role="main" class="container">
                <h1>WorldCup 2014 選手一覧</h1>
                </br>
                <table class="table table-striped table-hover table-sm table-responsive-sm">
                    <thead>
                        <tr>
                            <th scope="col">#</th>
                            <th scope="col">country</th>
                            <th scope="col">uniform_num</th>
                            <th scope="col">position</th>
                            <th scope="col">name</th>
                            <th scope="col">club</th>
                            <th scope="col">birth</th>
                            <th scope="col">height</th>
                            <th scope="col">weight</th>
                            <th scope="col">total_goals</th>
                        </tr>
                    </thead>
                    <tbody>
                        @foreach ($players as $player)
                        <tr>
                            <td>{{ $player->id }}</td>
                            <td>{{ $player->c_name }}</td>
                            <td>{{ $player->uniform_num }}</td>
                            <td>{{ $player->position }}</td>
                            <td>{{ $player->name }}</td>
                            <td>{{ $player->club }}</td>
                            <td>{{ $player->birth }}</td>
                            <td>{{ $player->height }}</td>
                            <td>{{ $player->weight }}</td>
                            <td>{{ $player->t_goals }}</td>
                        </tr>
                        @endforeach
                    </tbody>
                </table>
                <div class="row justify-content-end">
                    {{ $players->links() }}
                </div>
        </main>
        <!-- /.container -->
        <script src="{{ asset('js/app.js') }}"></script>
    </body>
</html>

ルーター作成
routes/web.phpに下記を記述

web.php
Route::get('/', 'WelcomeController@index');
Route::resource('players', 'PlayerController');
Route::resource('countries', 'CountryController');
Route::resource('goals', 'GoalController');
Route::resource('pairings', 'PairingController');

課題はここから…

  1. テーブルビューを1つ(あるいは2つ)追加
  2. functionを1つ追加
  3. controllerからviewに変数渡し してこのツイートと同じ見た目になるようにします

答えはコチラ

Task 5はいくつか追加の課題もあります
1. レコード追加
2. 論理削除
3. phpMyAdminのインストール

イージーモードになるyps委員長のブログはこちら
miyupaca log ⇒ yps学習記録その5

以上でTask5は終了です。
(ここでかなりの脱落者が出ましたが、今は答えもGitHubに載っているのでコピペでもいけてしまうかと思います…)