共同開発まとめ

初めに
---------------------------------------
実務に近い経験を積みたい！と思い、共同開発のコミュニティに参加しECサイトを作成しました。
共同開発するにあたって苦労した点や、各機能実装の際に参考にした記事や教材について記事にまとめました。

アプリの概要
---------------------------------------
ご当地の美味しいものをお取り寄せできるECサイト。
アプリURL https://www.tomtom-blog.net 
※テストアカウント
メールアドレス test@co.jp パスワード123456789123でログインできます。
GitHub   https://github.com/KawataTsutomu/yanbaru_ec_traning


**使用画面のイメージ**
![使用イメージ.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/983658/56b10107-0261-2975-c59f-d679393e0acd.gif)

使用技術
---------------------------------------
- **フロントエンド**
    - HTML / CSS / Bootstrap
- **バックエンド**
    - PHP 7.2.34
    - Laravel 6.18.36
- **インフラ**
    - Vagrant + VirtualBox + Docker
    - CentOS 7.3.1611
    - Apache 2.4.6　MySQL 5.7 / PHPMyAdmin
    - AWS ( VPC, EC2, RDS, IAM, IGW, ELB, Route53 )

開発環境、インフラ構成図
---------------------------------------
![開発環境.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/983658/824ef85f-8a90-01d8-7db5-4b9d9d0f862c.png)
![インフラ環境.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/983658/ac8e2eeb-ec38-6812-a79d-71f85fae90b0.png)

**AWSデプロイ参考記事**


- VPC構築参考
  
https://dev.classmethod.jp/articles/creation_vpc_ec2_for_beginner_1/

https://dev.classmethod.jp/articles/creation_vpc_ec2_for_beginner_2/

https://bcblog.sios.jp/construction-procedure-of-routetablescenario-aws/#3_AZ

- Docker環境構築

https://qiita.com/reoring/items/0d1f556064d363f0ccb8



機能一覧
---------------------------------------
- **ログイン関連**
    - ログイン、ログアウト機能  
- **ユーザー登録関連**
    - 新規登録、ユーザー情報確認、編集、退会機能
- **商品関連**
    - 商品詳細、検索機能
- **注文関連**
    - カート、注文詳細、キャンセル機能

　私は主にマイグレーション・シーダーファイル作成、ユーザー情報確認・修正、注文詳細を担当しました。

DB設計
---------------------------------------
**ER図**
![ER図.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/983658/a6d050f9-0065-8b48-1c33-e30404357535.jpeg)

苦労したこと
---------------------------------------
まず何をすればいいんだ...？と何も分からないところからスタート。考えているだけでは始まらない！とりあえず手を動かそう！とcodeを書いてみるもエラー連発で泣きそうになりました...w
ここでは特に印象に残っている点をまとめます。

環境構築
---------------------------------------
Vagrantを用いてDocker動作環境を構築し、Laravel立ち上げに成功！
翌日、PCを再起動し、作業を始めようとするapacheだけ立ち上がらない...
原因は、<font color="Red">正しい手順でDockerとVagrantを停止していなかった</font>からで、コンテナを壊してしまっていました...。

- docker-compose stop でDocker停止
- vagrant suspend でvagrant停止
- パソコンをシャットダウン

することで防ぐことができました。パソコンの電源を切るのと同じように正しい手順があることを学びました。

Git操作
---------------------------------------
意図して変更していないファイルも差分としてpushしてしまっていました。
commit,pushする前に何を変更した確認することを怠っていました。
色々な方法がありますが、VSCodeで確認するのが自分にあっているように感じました。
![スクリーンショット 2021-06-13 13.11.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/983658/59be947a-7d8e-05db-2819-458028077021.png)
①サイドバーの「ソース管理」のアイコンをクリック
②変更に変更されたファイルが表示される
③ファイルをクリックすると変更内容が表示される。(左が変更前で右が変更後)

個人で開発する分にはそれほど問題にはならないが、複数人で作業する現場では注意しなくてはいけないということを学びました。
「git push origin master は悪魔のコマンド」という高額な損害賠償のエピソードを知り、個人で開発する時よく使ってしまっていたのでゾッとしました...

DBからデータ取得
---------------------------------------
先に取りかかったユーザー情報確認画面では

- **Controller**

```UserController.php
public function show()
    {
        $user = Auth::user();
        return view('auth/user_info', ['user' => $user]);
    }
```
- **View**

```php:user_info.blade.php
@extends('layouts.app')

@section('content')

    <main>
        <div class="page-header mt-5 pt-5 text-center">
            <h4>ユーザ情報</h4>
        </div>
        <div class="row mt-5 mb-5">
            <div class="col-sm-6 mx-auto">

                <div class="mb-3">
                    <p class="contents">ユーザID</p>
                    <p class="contents-text">{{ $user->id }}</p>
                </div>

                <div class="mb-3">
                    <p class="contents">氏名</p>
                    <p class="contents-text"> {{ $user->last_name }} {{ $user->first_name }}</p>
                </div>

                <div class="mb-3">
                    <p class="contents" id="content-address">
                        住所
                    </p>
                    <div class="contents-text">
                        <p class="mb-1">〒{{ $user->zipcode }}</p>
                        <p class="mb-1">{{ $user->prefecture }}{{ $user->municipality }}{{ $user->address }}{{ $user->apartments }}</p>
                    </div>
                </div>
```
Authで欲しい情報(ログインしているユーザー情報)を取得できたので簡単だったので、次に担当した注文詳細画面で壁にぶち当たりました...

- **Route**

```php:web.php
Route::resource('orders', 'OrderDetailController', ['only' => ['show', 'edit']]);
```
- **Controller**

```php:web.php
class OrderDetailController extends Controller
{
    private const SHIPMENT_STATUS_PREPARE = 1;
    private const SHIPMENT_STATUS_CANCEL = 2;

    public function show($id)
    {
        $orderDetail = OrderDetail::whereHas('order', function ($query) use($id) {
            $query->where('order_id', $id);
            })
            ->select('order_detail_number')
            ->first();
        // ログインしているユーザーの注文詳細、注文履歴で選んだ注文のキャンセル(注文状態)以外を取得
        $ordersHistory = OrderDetail::with('Product.category', 'shipmentStatus')
            ->whereHas('order', function ($query) {
                $query->where('user_id', Auth::id());
                })
            ->where('order_detail_number', $orderDetail->order_detail_number)
            ->where('shipment_status_id', '<>', self::SHIPMENT_STATUS_CANCEL)
            ->get();

        $userInfo = Auth::user();
        $subtotal = 0;
        $total = 0;

        //注文状態の判定
        $preparationOrder = OrderDetail::whereHas('order', function ($query) {
            $query->where('user_id', Auth::id());
            })
            ->where('order_detail_number', $orderDetail->order_detail_number)
            ->where('shipment_status_id', '=', self::SHIPMENT_STATUS_PREPARE)
            ->get();
        //$shipment_status_flg = true なら準備中、false なら発送済
        $preparationOrderFlg = $preparationOrder->isEmpty() ? false : true;

        return view('order/order_detail', compact('ordersHistory', 'userInfo', 'orderDetail', 'subtotal', 'total', 'preparationOrderFlg') );
    }

    public function edit($id)
    {
        // ログインしたユーザーと同じuser_idなら選択した注文を準備中をキャンセルへ変更
        $ordersHistory = OrderDetail::whereHas('order', function ($query) {
            $query->where('user_id', Auth::id());
            })
            ->where('order_detail_number', '=', $id)
            ->where('shipment_status_id', '=', self::SHIPMENT_STATUS_PREPARE)
            ->update(['shipment_status_id' => self::SHIPMENT_STATUS_CANCEL]);

        return redirect()->back();;
    }
}
```

しかしそのお陰で、クエリビルダを使ってデータベースを操作し、テーブルからデータを取得することや、定数を定義して数字に意味を持たせることによってcodeが読みやすくなることを学べました。

参考にしたURL
https://readouble.com/laravel/5.7/ja/queries.html


終わりに
---------------------------------------
壁にぶち当たってメンバーに相談した際、嫌な顔せずに、dd( );を使ったデバッグの方法など色々教えてもらい、感謝してもしきれません。本当ありがとうございます。
自分もそんなチームを助けられるエンジニアになれるよう、勉強を続け知識を深めていきたいと思います。
動作確認した不備が見つかったので時間を作り直していきます。
技術的な記事ではありませんが、最後まで読んでいただきありがとうございました。