【独学ポートフォリオ】野球観戦アプリ「Baseball Memory」を開発してみました（Rails × MySQL × Heroku × Docker）

# はじめに

はじめまして！sekkey_777と申します。

今年で29歳の社会人5年目です。

大学時代は、化学を専攻しており、白衣着て朝から晩まで実験していました。

新卒1年目は工場で勤務していましたが、3年目になる際に社内の公募でIT系の部署に移動し、現在まで2年ほどSIer的な業務に従事しております。

現職では主に総合テストなどの品質管理、ベンダーとの調整を任されることが多いです。

2022年の10月頃から簡単な自社サービスの改修にも携わっており、Python、TypeScript、AWS、Docker、SQLなどに触れていますが、開発の経験としては浅い方です。

私としては<font color="#3C899A">**もっと開発に携わりたい**</font>と思っているので、転職に向けて学習をしています。

今回、転職活動に向けてRuby、Railsでポートフォリを制作したため、紹介させてください！

今後のキャリアイメージとしては、現時点では<font color="#3C899A">**モダンな技術で開発を牽引できるテックリード**</font>になることを目標としております。

そのために、まずはバックエンドスキルを高めて自分の技術の軸としつつも、特定の領域に縛られることなくフロントエンドやインフラ領域など幅広い分野でスキルアップをしていく想定です。

:::note info
できれば、アドバイスやコメント、感想などいただけるとありがたいです！
Qiita記事のコメントでも、[Twitter](https://twitter.com/sekkey_777)のDMなどでも構わないです！
:::

# アプリケーションについて

### 制作したアプリケーションはこちら（公開停止しました）！！

https://app-baseball-memory-4db029a6bcf5.herokuapp.com/

### GitHubはこちら！！

https://github.com/sekkey777/app-baseball-memory

### アプリケーション概要
[Baseball Memory](https://app-baseball-memory-4db029a6bcf5.herokuapp.com/)というアプリケーションで、プロ野球の観戦記録に特化したアプリです。

観戦記録をカレンダーに表示したり、結果に応じて勝率などを算出できます。

![app-all.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658523/835d8aeb-3a3e-97be-fffe-bc6baecba436.gif)


### 想定しているユーザー
- 頻繁にプロ野球を観戦しに行く方
- 中長期的にプロ野球を観戦している方
- 自分が観戦した試合の結果を後で振り返りたい方

### アプリケーション詳細
- プロ野球の観戦記録をつけることができます
- どのくらい試合を見に行ったか、勝ったか、負けたかなどを一目で確認できます
- 観戦結果に応じて勝率や連勝記録などが算出されます
- 思い出を投稿することができます

### なぜこのアプリケーションを作ったか？
なぜこのアプリケーションを作ったかと言いますと、私自身のプロ野球を観戦しに行く機会が急に増えたからです！！！（自分ごとですみませんm(__)m）

2022年くらいからプロ野球を観戦する機会が増えました。

特定のチームを応援するというよりは、東京ドームや神宮球場、ZOZOマリンスタジアムなどいろいろな球場、チームを観戦して楽しんでいます。

野球観戦が趣味になると、前回いつ野球観戦行ったかな？、次の観戦予定いつだっけな？、自分が応援した試合の勝率はどのくらいかな？などなどを気になるようになってきました。

また、他にもそんな思いを抱いている方がいるのでは？とも思い、それらを管理できるアプリケーションを作ってみよう！と思い立って開発してみました！

アプリケーションとしては最低限の機能が整ったためリリースいたしましたが、まだまだアプリとしては機能不足で、今後いろいろな機能を追加していきたいと思っております！

# 実装機能一覧
現在リリースしているアプリの機能一覧です。
それぞれの機能について簡単に紹介します。
- ユーザーアカウント作成、修正
- ユーザーログイン、ログアウト
- 観戦記録登録、編集、削除
- 観戦結果に基づいて勝率や連勝記録などを表示する機能
- 観戦記録の一覧表示（リスト型、カレンダー型）
- 思い出の投稿、編集、削除
- 思い出へのいいね機能
- ゲストログイン機能

### 観戦記録登録、一覧
プロ野球の観戦記録を登録する機能です。
次項に記載している観戦結果分析と合わせて、本アプリケーションのメイン機能となります。観戦記録時に<font color="#3C899A">**得点を入力して登録すると、その値に応じて勝敗を自動で判定**</font>するような仕様となっています。得点が入力されていない場合は、予定されている試合としてカウントします。

観戦記録一覧は<font color="#3C899A">**カレンダー形式**</font>と<font color="#3C899A">**リスト形式**</font>の両方のパターンで見ることができます。
カレンダーの実装には<font color="#3C899A">**simple_calendar**</font>というgemを用いています。

![app-game.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658523/92bf16c9-ae8f-3a5e-3f99-149096b0ae6a.gif)

### 観戦結果分析
観戦記録一覧画面で自分が観戦した試合の勝率や、現在の連勝・連敗情報などを表示するようにしています。自分が観戦した試合結果の状況を一目で見れるように意識して、ページのトップにサマリーを表示する仕様としています。

![観戦記録分析.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658523/1c1d255e-8246-5298-ea37-a425e62bd389.png)

### 思い出投稿、一覧
観戦した思い出を投稿して共有できる機能です。
この機能が必要か微妙なところですが、<font color="#3C899A">**ページネーション、いいね機能、検索機能などを実装したかった**</font>ため機能として盛り込みました。本当は、投稿保存機能やコメント機能、タグを押下するとその検索一覧が表示されるなどの機能も実装する予定でしたが、現時点では未実装となっています。

![app-post.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658523/976e5e76-b44c-8f1f-48d6-4b981af17e46.gif)

### ゲストログイン機能
ポートフォリオとして作成しているため、簡単にログインしてアプリの中身を確認頂けるようにゲストログイン機能を実装しています。
ゲストユーザーにはユーザー情報の更新以外の機能は解放しています。

### レスポンシブデザイン対応
もちろん、スマホでも使えるようにレスポンシブデザインにも対応させました。CSSフレームワークでBootstrapを採用したため、レスポンシブデザインは簡単に実装できるかと思いましたが、結構苦戦しました。

![app-responsive-game.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658523/c3b26ac3-d367-e2dd-78d0-5ced1b907da4.gif)

:::note info
機能としては最低限のものとなっていますが、「アプリケーションの今後の予定」に記載している通り、まだまだ機能を追加していきたいと思っています。
:::

# 開発スケジュール（実績）

ポートフォリオを開発するにあたり、だらだら開発し続けることは良くないと思ったため、<font color="#3C899A">**自分の中である程度スケジュールを決めて開発に取り組みました**</font>。

ゴールデンウィーク（GW）前にアイデア出しを行い、GW中に開発着手し、6月中旬ごろにはリリースするイメージで開発を進めました。

仕事との兼ね合いなどもあったため、細かいスケジュールは決めずに開発を進めましたが、概ね予定通りに進めることができたと思っています。

| 開始日 | 終了日 | 工数 | タスク |
| --- | --- | --- | --- |
| 4/24 | 4/30 | 1w | アイデア出し |
| 5/1 | 5/3 | 3d | デザイン検討 |
| 5/3 | 5/4 | 2d | テーブル設計、ER図作成 |
| 5/3 | 5/4 | 2d | 技術選定 |
| 5/3 | 5/4 | 2d | 開発環境構築 |
| 5/3 | 6/5 | 4w | 開発、実装 |
| 6/5 | 6/11 | 1w | テスト実装 |
| 6/12 | 6/16 | 1w | 軽微修正、リリース準備（README、デモデータなど） |
| 6/17 | 6/18 | 2d | リリース |

# ポートフォリオに使用した技術

### 技術選定で意識したこと

- **生産性が高い、さらに、情報が多く学習しやすい技術を採用する**
    
    本アプリを開発するにあたり、バックエンドの言語およびフレームワークにはRubyと Ruby on Railsを採用しました。
    
    Rubyを採用した理由は、シンプルで直感的な構文を持つことに加え、MVCフレームワークが現状Ruby on Railsほぼ1択のため、今後のキャリアにおいても技術の軸に据えやすいと考えました（もちろん、他に色々とスキルを広げていくつもりです）。
    
    また、下記のようなWeb教材や参考書などの王道な教材が揃っており、より学習や情報収集がしやすいと考えました。
    
    - [Ruby on Rails ガイド](https://railsguides.jp/)
    - [Ruby on Rails チュートリアル](https://railstutorial.jp/)
    - [Everyday Rails - RSpecによるRailsテスト入門](https://leanpub.com/everydayrailsrspec-jp)
    - [現場で使える Ruby on Rails 5速習実践ガイド](https://amzn.asia/d/5jr4HgT)
    - [プロを目指す人のためのRuby入門［改訂2版］　言語仕様からテスト駆動開発・デバッグ技法まで](https://amzn.asia/d/abFdL6v)

- **実務で利用した技術を取り入れること**
    
    本アプリを開発するにあたり、実際の業務で利用経験のある技術を取り入れようと考えました。なぜなら、<font color="#3C899A">**あるプロジェクトで得た経験やスキルを他のプロジェクトに導入したり、別のチームに展開したりすることが大切**</font>と考えたからです。
    
    そのため、今回は実務で利用したDockerを活用して開発環境を構築いたしました。
    
    Railsアプリケーション、データベース、データベース管理ツール（phpMyAdmin）のコンテナをdocker-composeで立ち上がるように構築することで、ローカル環境に依存せず、簡単に開発環境を構築できるようにしました。
    

### 使用技術一覧

| バックエンド | version | 備考 |
| --- | --- | --- |
| Ruby | v3.1.4 | バックエンドの開発言語として採用（採用理由は前述） |
| Ruby on Rails | v6.1.7 | MVCフレームワークとして採用（採用理由は前述） |
| MySQL | v8.0.0 | データベースとして採用 |

| フロントエンド | version | 備考 |
| --- | --- | --- |
| Bootstrap | v5.0 | フロントエンドのCSSフレームワークとして採用（手軽に導入・利用できるため。実際、導入しながら学習したため、学習コストがあまりかかっていない） |

| インフラ、その他　 | version | 備考 |
| --- | --- | --- |
| Heroku | － | デプロイ先に使用 |
| AWS S3 | － | 画像の保存先として使用 |
| Docker | v23.0.5 | 開発、本番の環境差分をなくすため、また、ローカル開発環境の構築をスムーズに行うため採用 |
| docker-compose | v2.17.3 | 複数のコンテナを同時に立ち上げて管理するために使用 |
| phpMyAdmin | v5.2.1 | データベースの値などを手軽に確認、変更するためのツールとして採用 |
| GitHub | － | ソースコード管理に使用 |

# 設計、デザイン

### ER図

![ER.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658523/5d2bef21-6925-cf08-1d20-afd025767d74.png)


### デザイン

デザインのコンセプトを明確にするために、本アプリケーションの開発前にFigmaを活用してデザインのワイヤーフレームを作成しました。

これにより、開発中にデザインの試行錯誤をする必要がなくなり、統一感のあるデザインのアプリケーションを効率的に作成することができたと思います。

概ねデザイン通りに実装したつもりですが、デザイン変更や機能を省いて実装したため、完全に一致はしていないです。

https://www.figma.com/file/Jar5dZynnuTNm4YbxjvFqj/app-baseball-memory?type=design&node-id=0-1&t=etcqkTHsK1ZNxLbM-0

![Figma.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658523/450164cf-20d0-1093-eb55-2bba8ee85b57.png)

# コミットメッセージの種別

基本的に、以下の表に示すルールに基づいてコミットしています。

実業務のプロジェクトでGitHubを利用して開発しておりますが、以前の経験から、コミットの粒度が粗く、具体的な内容変更がわかりずらいという問題がありました。

そのため、本アプリケーションの開発では、<font color="#3C899A">**コミット粒度を細かくし、また、コミットメッセージには具体的な変更内容を1行で分かりやすく記述すること**</font>を意識しました。

さらに、コミットメッセージの先頭にはprefix（add、update、fixなど）を付けて、簡単に履歴を検索できるように工夫いたしました。

| prefix | 説明 |
| --- | --- |
| add | ファイル追加（ファイル追加、gemの追加など） |
| gem | gemの追加、修正 |
| feat | 新規機能追加 |
| update | 修正（仕様変更、デザイン変更など） |
| fix | バグ修正 |
| spec | テストコードの記載、修正 |
| remove | ファイル削除 |
| clean | リファクタリング、コメント挿入など |

# その他利用ツール、サービス

| ツール | 備考 |
| --- | --- |
| Figma | 簡単なデザインイメージを作成するために使用 |
| Draw.io | ER図を作成するために使用 |
| Notion | アイデア出し、要件定義、テーブル設計などのドキュメント管理に使用 |
| Canva | ファビコンを作成するために使用 |

# 工夫した点

- **Ajax通信による非同期処理**
    
    プロ野球の観戦記録一覧のページでは、カレンダー表示とリスト表示で切り替える機能を実装しています。しかし、これらの表示形式を切り替える際にページのリロードが発生し、ユーザーの利便性が低下すると感じました。
    
    そのため、非同期処理を利用して表示形式の切り替えを実現しました。ボタンを押すたびにページ全体をリロードすることなく、データを非同期で取得し表示を切り替えることができるように工夫しました。
    
    いいね機能も同様に非同期処理で実装しています。
    

- **N＋１問題の対策を実施**
    
    Gameモデルなどは、他のモデルとのリレーションが複数組まれております。
    
    `includes`や`eager_load`などのメソッドでこれらのリレーションを効率的に取得することで、余分なクエリを削減しすることを意識しました。
    

- **モデルスペック、リクエストスペック、システムスペックの実装**
    
    現在の実務で総合テストを担当する機会が多く、また、手動でのテストに煩わしさを感じておりました。
    
    そこで、本アプリケーションの開発では、テストフレームワークであるRSpecを導入し、テストの自動化を試みました。
    
    基本的にモデルスペックやリクエストスペックなどの単体テストと、システムスペックなどの総合テストを記述し、機能を修正や追加時には、RSpecによるテストを実施して他の機能へ影響していないことを確認するよう心がけました。
    

# アプリケーションの今後の予定

今回アプリケーションをリリースしましたが、実際にユーザーに使っていただくには、まだまだ機能不足と認識しています。

そのため、<font color="#3C899A">**今後は以下のような機能を実装していきたい**</font>と考えています。

- 全ユーザーの勝率のランキング表示（自分を一覧に表示するか切り替え可能）
- 勝率や試合数に応じて一言コメント出したり称号獲得したりする機能
（「あなたは勝利の女神ですね♪」のような）
- 勝率算出の範囲を設定する機能
- ユーザープロフィールの充実（アイコン、自己紹介、好きなチームや選手）
- 各ユーザーのプロフィールや思い出一覧、勝率などが一覧で表示される
- ユーザーをフォローする機能
- 友人同士でグループを作り、勝率を競う機能
- 思い出投稿に対するコメント機能（Twitterのような）
- 思い出投稿の保存、保存した投稿一覧表示
- 思い出投稿に紐づいているタグを押下して検索できる機能
- プロ野球の試合日程を閲覧
- パスワードリセット
- 運営への問い合わせ

# ポートフォリオ制作を終えて

### 感想

今回のポートフォリオ制作で初めて自分が作ったWebアプリケーションをリリースしましたが、やはり<font color="#3C899A">**技術を活用して何かを作ったり、試行錯誤しながら課題を解決していくのは非常に楽しい**</font>なと思いました。

今回実装した機能は、そんなに難しい機能ではないと思いますが、<font color="#3C899A">**自分でモデルやデータ構造を設計し、それに基づいて処理をするためのロジックを考えて実装した**</font>ことは、非常に良い経験でした。

当然ながら躓くことも多々ありましたが、その度に<font color="#3C899A">**仮説を立て実行**</font>してみたり、<font color="#3C899A">**エラーログを調査**</font>したり、<font color="#3C899A">**データの受け渡しの流れを追って原因を追求**</font>したりと、色々な方法で解決を図る術を身につけられた気がします。なんでこんな簡単そうなことが実装できねーんだ。。。と自分の技術力のなさを嘆いたこともありましたが。。。

また、開発着手前は本当にできるのだろうかと思ったりもしましたが、手を動かしてみると意外と波に乗って実装できたとも思っています。要は<font color="#3C899A">**手を動かして実践していくことはとても大切**</font>だと改めて思いました。

### 反省点

今更ながら、こうすれば良かったかなと思ったことが2点あります。

1点目は、<font color="#3C899A">**テスト駆動型の開発**</font>にチャレンジしてみれば良かったと思いました。今回は先に機能を実装し、大体出来上がったタイミングでテストを実装しました。ただ、一部参考にさせて頂いた「Everyday Rails - RSpecによるRailsテスト入門」ではテスト駆動型の開発というものを推奨しているようでしたので、どうせなら現場に近い？開発の方法をとってみれば良かったと思いました。

2点目は、開発に着手する前に<font color="#3C899A">**アイデアについてTwitter等でヒアリング**</font>してみれば良かったと思いました。アプリの企画や機能などは私の独断と偏見になってしまっているため、あまりよろしくないと思っています。企業でのプロダクト開発では、ユーザー目線で開発することも心がけていると思いますので、そのような心がけが足りていなかったと思っています。

### 今後取り組みたいこと

今後自分の技術力向上のためにも、以下のような項目に取り組んでいきたいと思っております。

<font color="#3C899A">**エンジニアや技術者として活躍していくためには、日々のスキルアップは欠かせない**</font>と思いますので、これからもいろんな技術に触れて総合力の高いエンジニアを目指していこうと思います。

- インフラをHerokuからAWS環境に移行
- Railsのapiモードで実装する
- モダンフロントエンドの導入（Vue、React、MUI、tailwindcss、ChakraUI）
- デプロイ自動化（GitHub Actionsの導入）
- GA4の導入（ユーザーの動線分析）
- 何かしらのAPI連携を活用した機能の導入

# 最後に

ここまでご覧いただきありがとうございます。

色々考えながら実装勧めてきましたが、初学者のため、間違った設計や、コードの拙さなど多々あると思っております。

その際は、ご指摘、ご教示頂けますと幸いです。