業務未経験からRails、AWS、Dockerで育児系Webアプリを開発してみた【企画〜デプロイ】

# はじめに
　<font color="Green">**Rails**</font>、<font color="Green">**AWS**</font>、<font color="Green">**Docker**</font>、<font color="Green">**CircleCI**</font>で育児系Webアプリを開発してみましたので紹介させていただきます。

　**この記事でわかること**
　　・Webアプリケーションの作成手順（DB設計、インフラ構成）
　　・作成中苦労したこと、反省点

#### 自己紹介
- 現職：プラント設計

- 未経験からエンジニア転職目指して2020年8月1日から勉強中。

## １.アプリ概要
育児特化型の相談アプリです。

* __主要機能__
  * __相談機能__
  * __アンケート機能__

WebアプリURL : https://www.sukusuku-app.com/
(PC推奨)

GitHub URL : https://github.com/SHOGOHORI/sukusuku_ver2

![スクリーンショット 2021-01-29 16.06.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687088/e85b6816-3963-9278-3e38-1b523a35d01b.png)


今回作成したのはver.2になります。
ver.1記事 →　[プログラミング学習歴１ヶ月半からWebアプリを開発してみた](https://qiita.com/shogo-1988/items/72334b27a5b7f8e43ff8)

### デモ

* __相談投稿__<br>
![相談.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687088/f7ea3b37-6fa2-fe1f-d0ee-4ff854fa3c75.gif)


* __投票__<br>
![アンケート.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687088/ecb16118-d172-7e43-d786-60faa85ec17b.gif)

## 2.開発背景
　去年長男が生まれたのをきっかけに、僕は２ヶ月間育児休暇を取りました。
　そして生まれた直後、これから２人で育児頑張るぞ！と意気込んだ矢先、妻が感染症により高熱を出し、入院する、しないの騒ぎになりました。結局入院はしませんでしたが１〜２週間ほどずっと熱は下がらず寝たきりになり、私一人で育児をしていました。
　生まれたばかりの一つ命を預かるという、とてつもない責任を感じていました。孤独と不安で押しつぶされそうな状況でした。その時の経験から、同じような状況にいるママ、パパの不安を少しでも埋めたいという思い、SNSに近い形の相談アプリを作成しました。

　そういった背景から以前ver.1を作成しましたが、いくつか課題があり改善するために、ver.2を作成しました。

## 3.作成期間
　**2020年11月1日から2021年1月14日（75日間）**
![スクリーンショット 2021-01-22 11.20.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687088/bdba8083-af9a-acf4-5503-8f12eed75a23.png)

育児もしつつ、一日平日3〜6時間、休日8時間ぐらい作成に費やしました。

## 4.使用技術

* __開発環境__
  * __Mac Catalina(10.15.7)__
  * __Docker 20.10.2 / docker-compose 1.27.4__
  * __Visual Studio Code__

* __フロントエンド__
  * __jQuery 3.5.1__
  * __HTML / Sass / Bootstrap__

* __バックエンド__
  * __Ruby 2.7.2__
  * __Rails 6.0.3__

* __インフラ__
  * __CircleCI__
  * __Nginx 1.12.2__
  * __MySQL 8.0.22__
  * __AWS__ (VPC, EC2, ALB, ACM, S3, RDS, Route53, EIP, IAM)
  * __Capistrano3__

* その他使用ツール
  * draw.io(ワイヤーフレーム、ER図、サイトマップ作成用)

## 5.機能一覧
* __ユーザー登録関連__(devise)
 * 新規登録、プロフィール編集機能
 * 削除機能
 * ログイン、ログアウト機能
      * ログインした際、フレンドリーフォワーディングする
      * ゲストユーザーログイン機能
 * ユーザーマイページ
      * ユーザー投稿記事
      * お気に入り記事表示
      * 子どもの情報表示

* __子どもの情報登録関連__
  * 新規登録、編集機能
  * 削除機能
  * 子どもの情報詳細ページ

* __相談投稿機能__
  * 一覧表示、記事詳細表示、投稿、画像アップロード、編集
  * 投稿削除
  * コメント投稿、コメント返信（モーダルウィンドウ）
  * 受付終了機能

* __アンケート機能__
  * 一覧表示、記事詳細表示、投稿、画像アップロード、編集
  * 回答項目設定
  * 回答期限設定
  * コメント投稿（モーダルウィンドウ）

* __アンケート投票機能__
  * アンケート集計
  * 円グラフへ結果表示(chartkick、highchart)
  * 投票取り消し

* __記事お気に入り機能__
  * Ajax対応
  * お気に入り数表示

* __閲覧数表示機能__

* __検索機能__(Ransack)
  * キーワード検索
  * タグ検索
  * 詳細検索
        * 相談orアンケート
        * 年齢の範囲検索
        * ソート

* __ページネーション機能__(kaminari)
 * Ajax対応

* __タグ切り替え機能__

* __Twitterシェア機能__
 * twitterカード設定 

* __画像アップロード機能__ (carrierwave, AWS S3)

* __テスト機能__ (RSpec)
  * 単体テスト
  * 統合テスト

## 5.要件定義
　今回は要件定義にある程度時間をかけました。
### a.リーンキャンバス
　まずどんな技術を使うか、どんな機能を実装するかよりもWebアプリを作るバックグラウンドが重要だと感じましたので、リーンキャンバスを作成しました。このリーンキャンバスを作成する段階で類似アプリを研究しどう差別化を図るか、検討しました。

![リーンキャンバスver2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687088/888ff019-1fb3-2d08-33da-91d936bcd029.png)

### b.サイトマップ

 次にどういったアプリケーションにするか考えながら、サイトマップを作成しました。

![サイトマップ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687088/d7b4abf3-b00d-0044-f91a-3ba850a65f4c.png)

 
### c.ワイヤーフレーム
　次にターゲットとする顧客を考慮してデザインを考え、ワイヤーフレームを作成しました。
　サイトの色合い等は**[happyhues](https://www.happyhues.co/)**を参考に、ロゴは**Photoshop**、ホーム画像は**[Canva](https://www.canva.com/)**で作成しました。

![ワイヤーフレームver2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687088/e557b19b-558f-ec78-0f02-e20e177f7dde.png)

### d.DB設計
　必要な機能が決まったら、ER図を作成しました。実際の挙動を想定してどういった情報が必要なのか？を意識しDB設計を行いました。
　また、各カラムの詳細に定義した[テーブル定義書](https://docs.google.com/spreadsheets/d/1TvVktXZPtrLlpxS2mJAdE3dkIZjo41ujKL53Q843fLY/edit#gid=1328997144)を作成しました。

![ER図ver2 17.05.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687088/881b33b7-27e0-e427-fabc-1d74069aa298.png)

### e.インフラ設計
　インフラ構成は開発環境に**Docker**、本番環境に**AWS**、CI/CDパイプラインに**CircleCI**を使いました。**Capistrano**でデプロイ後**slack**に通知が来るよう設定しました。
![インフラ構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687088/3b3f5a57-cc12-271a-e806-30bf78fe46bb.png)


#### ｆ.Git issueへ作業を登録
　ここまで設計できれば作業内容を明確にできるので、作業手順を**[Git issue](https://github.com/SHOGOHORI/sukusuku_ver2/issues?page=1&q=is%3Aissue+is%3Aclosed)**にまとめました。
　またGitでバージョン管理する際は、**Git flow**を使用し、細かくコミットしました。

[Git-flowって何？](https://qiita.com/KosukeSone/items/514dd24828b485c69a05)
[GitHub Cheat Sheet（日本語訳)](https://github.com/sotayamashita/github-cheat-sheet)

## 6.工夫した点、苦労した点

#### 質問できる環境構築
　もともとオンラインのプログラミングスクールに少しだけ通っておりましたが、私にとってプログラミング学習にスクールは必要ないと判断したため、解約しました。そのためどうしてもわからない部分に関しては、下記の方法で解決を進めました。

- **<font color="blue">勉強会に参加し人脈広げ、質問できそうな人を探す**

- **<font color="blue">プログラミング質問サイトを活用する**

- **<font color="blue">スポットでMENTAと契約する**

#### JavaScript
　今回、子どもの情報登録のネストフォーム、フォームの有効無効、ページネーション、タブ切り替え等、スポットでJavaScript（jQuery）を使用しました。
　jQueryでのフロント設計は本当に苦労しました。色々試した挙げ句、結果あまり保守性の高くないコードになった気がします。
　また、タブ+ページネーションの部分は、いまだに上手くいってません。（タブを切り替えるとページネーションが上手く挙動しない）

#### アンケート機能
　アンケート機能はデータベース設計から投票集計方法を考えるのに苦労しました。
　アンケート機能は次の条件のもと設計しました。

- **投票項目の上限は4項目**

- **投票期間は1〜7日間で選べる**

- **1つのアンケートにつき、1ユーザー1投票まで**

- **ログイン前は投票内容の確認のみで、投票できないようにする**

- **投票後、評価結果の円グラフを表示、投票できないようにする**

- **投票後、投票取り消しができる**

- **投票受付終了後は投票、投票取り消しができないようにし、評価結果を表示**
　
　この条件をもとにフロント、サーバーサイドともに制限をかけたかったのですが、一部サーバーサイドの制限方法がわからずフロント部分のみの制限になった条件もあります。
　また、アンケート集計結果の円グラフ表示ようにChart.jsを使用しましたが、記載方法に苦労しました。

[Chart.js日本語ドキュメント](https://misc.0o0o.org/chartjs-doc-ja/)

#### EC2のSSH鍵、AWSアクセスキーの置き場所
　当初はDockerコンテナ上で、CircleCIでCIパイプライン構築したあとは、CircleCI上でCapistranoを使用し自動デプロイしていましたが、SSH鍵、AWSアクセスキーの置き場に悩みました。
　なかなか、assets　precompileの壁が超えられず、一度間違ってGithubにAWSアクセスキーを上げてしまい、AWSから怒られ、AWSアクセスキーを変更しました。
　セキュリティは慎重にしなければならないと身を持って学びました。

[AWS アクセスキーを管理するためのベストプラクティス](https://docs.aws.amazon.com/ja_jp/general/latest/gr/aws-access-keys-best-practices.html)
[Capistrano公式ドキュメント](https://capistranorb.com/)

## 7.今後やりたいこと

* __フロントエンド__
 * レスポンシブル対応
 * タグ+ページネーションの挙動の修正（アンケートタブでページ移動すると相談タブに戻る）
 * 検索条件保持
 * Vue.js導入

* __バックエンド__
 * アンケート項目を同じ内容を登録できないようにする（何故か``validates_uniqueness_of``でできなかった）
 * 年齢月齢の範囲検索（現状は月齢の累積でしかできない）
 * ユーザーフォロー、アンフォロー機能
 * テストコードの充実
 * 子どもの情報詳細ページにミニ日記
 * 管理ユーザー登録機能

* __インフラ__
 * AWSでECSでデプロイ
 * EC2、RDSの冗長化
 * メールサーバー構築

* __その他__
 * リファクタリングをし運用・保守をしやすいコードを目指す
 * 利用規約作成
 * どのように収益化を目指すか練る
 * 想定する顧客に近い立場の人に使用してもらいフィードバックをもらう

その他実装したい機能は**[Issue](https://github.com/SHOGOHORI/sukusuku_ver2/issues)**にまとめていきます。

# まとめ
　今回のWebアプリを開発してみて、下記のことを学びました。

- **<font color="red">インフラ面はセキュリティ面、保守性を意識してもっと勉強が必要**

- **<font color="red">人脈を広げ、いつでも相談できる環境を構築することは、アプリの質向上に必要**

- **<font color="red">データベースの設計を勉強してもっと複雑なものも設計できるようになりたい**

　今後SukuSukuをどんどんアップデートしていくか、他のアプリケーションを作成するか、検討中ですが、次回はマネタイズを視野に入れて開発したいと思います。
　使っていただいてなにかコメントありましたら厳しいものでもいいのでどしどしお願いします！