Ruby on Railsでポートフォリオを作成、AWS(EC2)にデプロイ


## はじめに
はじめまして。
私は元プロボクサーで、WEBエンジニアへ転職活動中です！

減量経験を元に、Ruby on Railsでポートフォリオを作成しました。
作成したアプリについて説明できればと思います。

## アプリ概要
* 体重に関連する内容に特化した投稿システム
    * ダイエットの記録(体重、体脂肪率、食事、運動、メモ)ができる
    * 体重の変遷をグラフで表示できる
    * 他の人の記録をチェックできる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966559/454ee997-2bf2-9ad8-5e11-28f8430ae298.png)

## アプリを作った背景
元々プロでボクシングをやっていたので、体重コントロールに関心があります。
以下を考え、アプリを作成しました。

* 自分の日常生活を記録したい
* 自分の体重の変遷を可視化したい
* 成功しているひとの行動パターンを知りたい
* ダイエットという共通の目的を持つ人たちと、フォロー、コメント、いいねを通して刺激し合いたい

## 機能一覧
1. ログイン機能(CRUD)
2. プロフィールページ
3. 投稿機能(CRUD)
4. いいね
5. コメント
6. フォロー(お気に入りユーザー機能)
7. ゲストユーザーログイン機能
8. 検索機能
9. グラフ
10. 画像投稿


## Figma
https://www.figma.com/file/KKLdUx3wfGaj2vhnJH1rcM/%E4%BD%93%E9%87%8D%E7%AE%A1%E7%90%86%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0?node-id=11%3A411&t=YY0wF5d16h6cinMs-1

## ER図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966559/f7152641-7250-d7f5-b188-386f58dd9f1e.png)

## データベース定義書

<table>
  <caption>テーブル名：ユーザー / User</caption>
  <thead>
    <tr>
      <th></th><th>項目名   </th><th>カラム(属性)名</th><th>型</th><th>長さ　</th><th>not Null</th><th>default</th><th>主キー</th><th>index</th><th>メモ・補足</th>
    </tr>
  </thead>
  <tr>
    <td>1</td><td>ユーザーid</td><td>id</td><td>bigint</td><td></td><td>○</td><td>PK</td><td></td><td></td><td>自動</td>
  </tr>
  <tr>
    <td>2</td><td>名前</td><td>name</td><td>string</td><td>20</td><td></td><td></td><td></td><td></td><td></td>
  </tr>
  <tr>
    <td>3</td><td>email</td><td>email</td><td>string</td><td>100</td><td>○</td><td></td><td></td><td>○</td><td></td>
  </tr>
  <tr>
    <td>4</td><td>作成日時</td><td>created_at</td><td>datetime</td><td></td><td>○</td><td></td><td></td><td></td><td>自動</td>
  </tr>
  <tr>
    <td>5</td><td>更新日時</td><td>updated_at</td><td>datetime</td><td></td><td>○</td><td></td><td></td><td></td><td>自動</td>
  </tr>
  <tr>
    <td>6</td><td>パスワード</td><td>password</td><td>string</td><td>6以上</td><td>○</td><td></td><td></td><td></td><td></td>
  </tr>
  <tr>
    <td>7</td><td>リメンバーダイジェスト</td><td>remember_digest</td><td>string</td><td>○</td><td></td><td></td><td></td><td></td><td></td>
  </tr>
  <tr>
    <td>8</td><td>管理者</td><td>admin</td><td>boolean</td><td></td><td></td><td>FALSE</td><td></td><td></td><td></td>
  </tr>
  <tr>
    <td>9</td><td>自己紹介</td><td>self_introduction</td><td>string</td><td></td><td></td><td></td><td></td><td></td><td></td>
  </tr>
  <tr>
    <td>10</td><td>目標体重</td><td>target_weight</td><td>float</td><td></td><td></td><td></td><td></td><td></td><td></td>
  </tr>
  <tr>
    <td>11</td><td>目標体脂肪率</td><td>target_body_<br>fat_percentage</td><td>float</td><td></td><td></td><td></td><td></td><td></td><td></td>
  </tr>
  <tr>
    <td>12</td><td>画像</td><td>image</td><td>string</td><td></td><td></td><td></td><td></td><td></td><td></td>
  </tr>
  <tr>
    <td>13</td><td>パスワードダイジェスト</td><td>password_digest</td><td>string</td><td></td><td></td><td></td><td></td><td></td><td></td>
  </tr>
</table>

<table>
  <caption>テーブル名：投稿 / Article</caption>
  <thead>
    <tr>
      <th></th><th>項目名　　　</th><th>カラム(属性)名</th><th>型</th><th>長さ　</th><th>not Null</th><th>default</th><th>主キー</th><th>index</th><th>メモ・補足</th>
    </tr>
  </thead>
  <tr>
    <td>1</td><td>投稿id</td><td>id</td><td>bigint</td><td></td><td>○</td><td></td><td>PK</td><td></td><td>自動</td>
  </tr>
  <tr>
    <td>2</td><td>ユーザーid</td><td>user_id</td><td>integer</td><td></td><td>○</td><td></td><td>FK</td><td></td><td>usersテーブルに紐づく</td>
  </tr>
  <tr>
    <td>3</td><td>作成日時</td><td>created_at</td><td>datetime</td><td></td><td>○</td><td></td><td></td><td></td><td>自動</td>
  </tr>
  <tr>
    <td>4</td><td>更新日時</td><td>updated_at</td><td>datetime</td><td></td><td>○</td><td></td><td></td><td></td><td>自動</td>
  </tr>
  <tr>
    <td>5</td><td>日にち</td><td>date</td><td>date</td><td></td><td></td><td></td><td></td><td></td><td></td>
  </tr>
  <tr>
    <td>6</td><td>体重</td><td>weight</td><td>float</td><td></td><td></td><td></td><td></td><td></td><td></td>
  </tr>
  <tr>
    <td>7</td><td>体脂肪率</td><td>body_fat_percentage</td><td>float</td><td></td><td></td><td></td><td></td><td></td><td></td>
  </tr>
  <tr>
    <td>8</td><td>食事(朝)</td><td>meal_morning</td><td>string</td><td>50</td><td></td><td></td><td></td><td></td><td></td>
  </tr>
  <tr>
    <td>9</td><td>食事(昼)</td><td>meal_lunch</td><td>string</td><td>50</td><td></td><td></td><td></td><td></td><td></td>
  </tr>
  <tr>
    <td>10</td><td>食事(夜)</td><td>meal_dinner</td><td>string</td><td>50</td><td></td><td></td><td></td><td></td><td></td>
  </tr>
  <tr>
    <td>11</td><td>食事(間食)</td><td>meal_snack</td><td>string</td><td>50</td><td></td><td></td><td></td><td></td><td></td>
  </tr>
  <tr>
    <td>12</td><td>運動</td><td>exercise</td><td>string</td><td>50</td><td></td><td></td><td></td><td></td><td></td>
  </tr>
  <tr>
    <td>13</td><td>メモ</td><td>memo</td><td>string</td><td>150</td><td></td><td></td><td></td><td></td><td></td>
  </tr>
</table>

<table>
  <caption>テーブル名：いいね / Like</caption>
  <thead>
    <tr>
      <th></th><th>項目名　　　</th><th>カラム(属性)名</th><th>型</th><th>長さ　</th><th>not Null</th><th>default</th><th>主キー</th><th>index</th><th>メモ・補足</th>
    </tr>
  </thead>
  <tr>
    <td>1</td><td>いいねid</td><td>id</td><td>bigint</td><td></td><td>○</td><td></td><td>PK</td><td></td><td></td>
  </tr>
  <tr>
    <td>2</td><td>ユーザーid</td><td>user_id</td><td>integer</td><td></td><td>○</td><td></td><td>FK</td><td></td><td>Userテーブルに紐づく</td>
  </tr>
  <tr>
    <td>3</td><td>投稿id</td><td>article_id</td><td>integer</td><td></td><td>○</td><td></td><td>FK</td><td></td><td>Articleテーブルに紐づく</td>
  </tr>
</table>

<table>
  <caption>テーブル名：コメント / Comment</caption>
  <thead>
    <tr>
      <th></th><th>項目名　　　</th><th>カラム(属性)名</th><th>型</th><th>長さ　</th><th>not Null</th><th>default</th><th>主キー</th><th>index</th><th>メモ・補足</th>
    </tr>
  </thead>
  <tr>
    <td>1</td><td>コメントid</td><td>id</td><td>bigint</td><td></td><td>○</td><td></td><td>PK</td><td></td><td></td>
  </tr>
  <tr>
    <td>2</td><td>投稿id</td><td>article_id</td><td>integer</td><td></td><td>○</td><td></td><td>FK</td><td></td><td>Articleテーブルに紐づく</td>
  </tr>
  <tr>
    <td>3</td><td>ユーザーid</td><td>user_id</td><td>integer</td><td></td><td>○</td><td></td><td>FK</td><td></td><td>Userテーブルに紐づく</td>
  </tr>
  <tr>
    <td>4</td><td>コメント</td><td>content</td><td>string</td><td>100</td><td>○</td><td></td><td></td><td></td><td></td>
  </tr>
  <tr>
    <td>5</td><td>作成日時</td><td>created_at</td><td>datetime</td><td></td><td>○</td><td></td><td></td><td></td><td>自動</td>
  </tr>
  <tr>
    <td>6</td><td>更新日時</td><td>updated_at</td><td>datetime</td><td></td><td>○</td><td></td><td></td><td></td><td>自動</td>
  </tr>
</table>

<table>
  <caption>テーブル名：フォロー / Follow</caption>
  <thead>
    <tr>
      <th></th><th>項目名　　　</th><th>カラム(属性)名</th><th>型</th><th>長さ　</th><th>not Null</th><th>default</th><th>主キー</th><th>index</th><th>メモ・補足</th>
    </tr>
  </thead>
  <tr>
    <td>1</td><td>フォローid</td><td>id</td><td>bigint</td><td></td><td>○</td><td></td><td>PK</td><td></td><td></td>
  </tr>
  <tr>
    <td>2</td><td>ユーザーid</td><td>user_id</td><td>integer</td><td></td><td>○</td><td></td><td>FK</td><td></td><td>Userテーブルに紐づく</td>
  </tr>
  <tr>
    <td>3</td><td>ユーザーid</td><td>user_id</td><td>integer</td><td></td><td>○</td><td></td><td>FK</td><td></td><td>Userテーブルに紐づく</td>
  </tr>
</table>


## ポートフォリオのURL
* GitHub
https://github.com/box-7/weight_control_app

* URL
https://weight-control.xyz/

* ゲストログイン
ゲストログインする場合は下記画像をご確認ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966559/4154ea3a-069b-f551-8aba-0d2aca173657.png)

## 使用技術
* フロントエンド
HTML/CSS(SCSS)
bootstrap-sass (3.4.1)
jquery-rails (4.4.0)

* バックエンド
Ruby 2.7.5
Ruby on Rails 5.1.7

* インフラ
AWS（EC2、Route53、CroudFront、ACM）
Nginx
Unicorn

* データベース
SQLite3

## できること
### 自分の生活を記録する
* 毎日の体重、体脂肪率、食事、運動、メモを記録できる
* 1ヶ月単位の体重の推移をグラフで確認できる
* 自分の投稿の中から、キーワード、日にちで投稿を絞り込める

新規投稿
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966559/5721add9-d3f2-d8e7-f589-34619e4dae5a.png)

投稿一覧
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966559/f3d702bc-2215-21b5-82a9-9e8ba096a43b.png)

### 他の人の情報を確認する
* HOME画面
    * 投稿を最新のものから順番に確認できる
    * 投稿一覧には、減量開始からの減量体重数値と、体脂肪率を記載
    * 投稿にいいね、コメントをつけることができる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966559/e688e5b6-ce61-80bf-33f5-a7c89111dea8.png)

* 他の人の投稿一覧
    * 毎日の体重、体脂肪率、食事、運動、メモを一覧で確認できる
    * 1ヶ月単位の体重の推移をグラフで確認できる
    * キーワード、日にちで投稿を絞り込める
    * 投稿にいいね、コメントをつけることができる
    * ユーザーをフォローできる
※ 上記画像と同じ内容のため画像は省略

## 苦労したところ

* グラフ
    体重、体脂肪率の2軸で作成することに苦労しました。
    Ruby on Railsで情報を抽出し、JavaScriptに値を渡し、ビュー上で描画する一連の流れが難しかったです。
    
    「キーワード、日付の検索条件を残したまま、グラフの年月絞り込みを変える」、「グラフの年月絞り込みを残したまま、キーワード、日付の検索条件を変える」が難しかったです。
    ビューとコントローラーの値の受け渡し方法について調べて試行錯誤することで解決できました。

* デザイン
    サイト全体のデザインをどのように統一感のあるものにするかで悩みました。
    いろいろな記事を探し、BootStrapで実装していくのが良さそうだと思いました。
    BootStrapのテンプレートから自分のサイトに適用できるデザインを探して、適用させました。

* AWS
    VimやLinuxコマンドの操作が難しかったです。使ったことがあまりないので、調べながら実装しました。
    デプロイを何回やってもAWS上でアプリを確認できず、時間を多く使ってしまいました。
    原因はnginxファイルでアプリ名に誤りがあったためでした。
    細かいところにも注意を払わなければならないと思いました。

* HTTPS化
    お名前.comでドメインを取り、Route53、CroudFront、ACMで設定しました。
    AWSにほとんど触れたことがなかったのでとても苦戦しました。
    すぐにHTTPで表示することはできたのですが、そこからHTTPS化するのが大変でした。
    CloudFrontでキャッシュさせないで、サーバー本体と通信させるようにする設定が難しかったです。
    友人の力を借りながら、なんとか実装できました。

## 感想
ポートフォリオを作るのは2回目ですが、今回はゼロから作成しました。

* よかったこと
    ネットで情報を調べながら、グラフ機能やデザインなど、難しい機能も作成できました。
    詰まることもあったが、試行錯誤し解決できました。
    エンジニアの方に相談させていただいたが、文章のみでのやりとりだったため、質問力、問題の解決能力が上がりました(と思います)。
    企画からデプロイまで2ヶ月と、スピード感を持って開発できました。

* 改善点
    AWSのデプロイ、HTTPS化までしましたが、理解が甘いので改めて勉強が必要です。
    JavaScriptも理解が甘いので改めて勉強が必要です。
    これからRSpecを使ってテストをしていきます。