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の結果**

```SQL
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の参考例**

```SQL
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;までを削除（↓の部分）

```SQL
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

```SQL
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に以下をコピペ

```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. テーブルビューを１つ（あるいは２つ）追加
2. functionを１つ追加
3. controllerからviewに変数渡し
して[このツイート](https://twitter.com/yotaro__ok/status/1296939915704332289)と同じ見た目になるようにします

答えは[コチラ](https://github.com/yotaro-ok/yps/blob/master/task_5.md)

Task 5はいくつか追加の課題もあります
1. [レコード追加](https://twitter.com/yotaro__ok/status/1298257156483870721)
2. [論理削除](https://twitter.com/yotaro__ok/status/1298973532647378944)
3. phpMyAdminのインストール

イージーモードになるyps委員長のブログはこちら
miyupaca log ⇒ [yps学習記録その5](https://paca-gatsby.netlify.app/2020-08-21/)

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