【個人開発】独学開始から2ヶ月の実務未経験者が、制作期間1ヶ月で作ったポートフォリオアプリ

#0. はじめに

実務未経験・`独学開始から約2ヶ月`のいわゆる**”駆け出しエンジニア”**の私が、`制作期間約１ヶ月`でポートフォリオのWebアプリを0から作ってみたので、ご紹介させて頂きたいと思います。

昨今いろんな先輩方のポートフォリオ作成記事が多く存在しますが、この記事も同じ初学者の方にとって、何か参考になれば幸いです。

###　簡単に自己紹介
* 現在24歳、大学を卒業し金融系企業に勤める3年目OL
* Web・IT技術に惹かれて独学でのプログラミング学習を開始し、さらにプログラミングの虜になりエンジニアへの転身を決意
* 好きなマンガはワンピース（人生の教科書）


# 1.使用技術
フロントエンド：JavaScript / jQuery 3.6.0 / Ajax
バックエンド：PHP 7.3.11 / Laravel 8.38.0
データベース：MySQL
インフラ：Heroku
バージョン管理：Git / GitHub

# 2.実際のアプリ紹介
タイトル「Golf Score Share」
![画面収録 2021-06-08 21 19 28](https://user-images.githubusercontent.com/78901624/121184196-ce370680-c89f-11eb-8729-daf893e55e2e.gif)

**URL（スマホ・タブレット専用）**
http://golf-score-share.herokuapp.com/golf
※heorku無料版では30分ごとに使っていなければwebサーバーが停止する(スリープ状態)ようなので、起動に時間がかかるかと思います。ご了承くださいm(__)m

**GitHub**
https://github.com/hinakonagao/golf-score-share

###アプリ概要
ゴルフコースを回る際、Web上でスコアカードを共有し、一緒に回るメンバーが各々のスマホから共有のスコアカードを見たり、スコアを書き込めるアプリです。

### 使い方
**スコアカード作成者**
1. start a new gameをタップします。
2. ゲーム名・パスワードを決め、start a new gameをタップしてスコアカードを作成します。※過去に使われているゲーム名は使えません。
3. スコアカード画面に遷移します。 


**スコアカードへの参加者**
1. join the game をタップします。
2. 作成者が登録したのと同じゲーム名・パスワードを入力し、join the gameをタップしてスコアカードに参加します。※ゲーム名・パスワードの一致が確認できなけれなエラーになります。
3. スコアカード画面に遷移します。

**スコアカード画面の使い方**
・作成者・参加者の誰でも、スコアカードに書き込むことが出来ます。
・スコアカードに書き込んだ時点で、自動的にデータは更新されます。（Ajax通信でデータ保存）
・他の人が更新した内容を自分の画面に反映させる為には、updateボタンを押してください。
(例)Aさんがスコアカードにhole1のスコアを入力。→Bさんが自分のスマホのupdateボタンを押すと、Aさんが入力したスコアがBさんの画面にも反映する。


###開発背景

* 私自身ゴルフが好きでコースを回ることがあり、こんなサービスが欲しいなと思っていました。ゴルフ仲間にも相談すると、「実現すれば是非使いたい」「便利で面白い」と賛同が得られ、ゴルフ好きには`需要がある`と考えました。
* `競合のいないブルーオーシャン`だった。（個人でスコアカードを保存するスマホアプリや、同じスマホアプリをダウンロードしている人同士でスコアカードを共有できるサービスはありますが、誰でも準備不要ですぐに使えるサービスは見つかりませんでした。）

#3.実装した機能

* スコアカード新規作成
* スコアカードが作成された際、プレーヤーのデータを自動生成
* スコアカードに参加（既に作成されたスコアカードと一致するゲーム名・パスワードを入力すると、そのスコアカードに参加できる）
* スコアカード編集（スコアカードに参加した人は誰でも編集可能）<br>
※編集したデータはAjax通信でデータベースへ保存


機能は少なく、シンプルなアプリかと思います。
ですがそれまでudemyなどで学習した、基本的なCRUD機能を持ったアプリやSNSアプリとは全く構成が違うので、どういう仕組みにすれば作りたい機能を実現できるのか**０から考える事が難しく**もあり、機能を実現するプログラムの流れを**自分なりに考えて調べて実装できた時は本当に楽しい**と感じました。

#4.サービス設計・ER図
スコアカードを作成するとRoomテーブルにレコードが作成されると同時に、RoomPlayerテーブルにプレーヤー4人のレコードが自動生成されます。

スコアカードのマス目一つ一つがinputタグになっており、RoomPlayerテーブルへデータをPOSTする窓口であると同時に、データベースに保存されているスコアを表示する機能も兼ねています。

|テーブル名 |説明  |
|---|---|
|Room  |スコアカード管理 |
|RoomPlayer  |スコアカードに紐づくプレーヤーの名前・スコアを管理 |

![スクリーンショット 2021-06-12 7 09 52](https://user-images.githubusercontent.com/78901624/121753409-42e29d00-cb4d-11eb-82d7-cc5ee7e34b26.png)

#5.工夫したこと
###バックエンド
* **SQL発行回数を最小限に**

〈当初〉RoomPlayerテーブルに4つのレコード（プレーヤー4人）を生成する際、1レコード生成するにあたり1回SQLを発行していました。

〈改善〉配列とinsert()を使って一気にデータ保存することで、SQL発行回数を4回→1回に抑えました。
<br>
* **スコアカード更新の際の通信削減**

〈当初〉スコアカードの値をひとつ変更する毎に、スコアカードのカラム全てについてデータベースの値を更新する処理を行なっていました。

〈改善〉フォームのinputタグにdata属性を指定し、jQueryで変更のあったカラムのみを取得することで、変更のあったカラムのみデータベースを更新する処理を可能にしました。
<br>
* **Ajaxを使用した非同期通信によるデータ保存**

スコアカードを更新した際は、Ajaxでデータベースへデータを保存するようにしました。

### フロントエンド（UI)
* **スコアカードの名前入力欄には、「名前を変更」という背景文字を表示**

この点は、以下のようにユーザーの声を反映して改善を繰り返してきました。

①プレーヤーのレコード生成時に、「プレーヤー１」「プレーヤー２」…というように名前の初期値をデータベースへ登録する。
→プレーヤー名を変更できることに気づいてもらえなかった。

②データベースへ登録する初期値を「名前を変更」にする。
→名前を変更する際、一度消さなければいけないのが面倒

③プレーヤーのレコード生成時、名前の初期値はnullとする。代わりにHTMLのinputタグのplaceholder属性で、「名前を変更」と背景文字を設定する。
<br>

* **スコアカードの表示方法**

まずスコアカード上にRoomPlayerテーブルの該当レコード4つをforeachで表示しまし、スコアカードの縦横をCSSで入れ替える事で、スマホで見やすい縦向きのスコアカードを実現しました。

#6.開発の進め方
このアプリ開発に取り組む前に、udemyの教材でLaravel・PHP・MySQLについて学びました。

* 【2日でできる】はじめての PHP 7 x Laravel 6 入門<br>
https://www.udemy.com/course/php7study/
* PHP+MySQL（MariaDB） Webサーバーサイドプログラミング入門<br>
https://www.udemy.com/course/php7basic/


これらでMVCモデルの全体像やPHP・MySQLの基本を勉強し、あとは**<font color="Crimson">作りながら、必要なことを学ぶ</font>**というやり方で進めました。
つまり、**実装する機能（アウトプット）をまず決めて、そのために必要な知識を勉強（インプット）する**ということです。

その際によく活用したサイトも紹介させていただきます。

* Laravel学習帳<br>
https://laraweb.net/
* ReaDouble<br>
https://readouble.com

あとは公式ドキュメントや、偉大な先輩方のQiita記事もたくさん参考にさせていただきました。
udemyで学習する際には公式ドキュメントなどほとんど読んだ事がありませんでしたが、しっかり読んでみると公式ドキュメントが一番分かりやすかったりして、勉強になりました。

#7.まだできていない・これからやりたいこと
まだまだ出来ていない事はたくさんあります😥
また、開発を進める途中で実装したいなと思う機能もどんどん出てきました。

* PHPUnitでのテスト
* AWSでデプロイ
* デバッグツールの活用（xdebug）
* Https化
* ログイン・ユーザー登録機能を追加し、過去のスコアカードを振り返れるようにする。
* 現在はスコアカードを更新する際、変更したデータの保存のみAjaxで行なっているが、他の人のスコアカードへの反映もAjaxで実装する。
* RoomPlayerテーブルにTotalカラムを追加する。
* コンペ機能を追加する。（複数組でラウンドを回る際、他の組みのスコア進捗も見られるように）
* 前半後半の9ホールずつ表示し、タブで切り替えられるSPAにする。

#8.さいごに
初めての個人開発だったので、どのぐらい時間が掛かるものなのか、目標設定の見当もつきませんでした。
そこで**まず1ヶ月を目安として、あれこれと欲張らず最低限の機能だけでも「やり切る」**ことを重視して開発に取り組みました。

結果、メイン機能は実装を終え無事デプロイまで辿り着きました。
先述の通り、まだまだ出来ていない事・やりたい事はあるので、これから少しずつ改修していきたいなと思います。

開発の進め方については、**<font color="Crimson">実装する機能（アウトプット）をまず決めて、そのために必要な知識を勉強（インプット）する</font>**方法は、やって良かった事と思っていて、これは是非同じ初学者の方々にもおすすめしたいです。
正直、udemyで作ったSNS風アプリをアレンジする…というようなことから始めれば良かったと思うこともあり、何度も挫けそうになりました。
ですが、udemyを真似て作るのとは比べ物にならないほど、自分で0から考えて調べてコードを書くと理解が深まりました。何より、自分の力で書いたプログラムが動く瞬間は、嬉しくて楽しくてニヤけずにはいられませんでした（笑）

####今後の最優先課題
MVCモデルやプログラムの流れについては少しだけ理解が出来たかなと思う一方、**Webの根本的な技術・仕組み**についてもっと知らなければいけないという課題を感じたので、勉強していこうと思います。
<br>
この記事について間違っている箇所があれば、ご指摘頂けると幸いです。
拙い文章でしたが、最後までご覧いただき本当にありがとうございました！！😊