【個人開発】野球観戦をもっと楽しめるサービス、「野球バカ実況」をリリースします！

## まえがき
私は未経験のエンジニアで約一年間Railsを中心に勉強していました。野球観戦を楽しめるサービスを開発してみました。野球が好きな人は読んでくれれば嬉しいです。後半には難しかった技術についても述べています。技術が好きだという人も是非読んでいただければ嬉しいです！

# サービスURL
#### サービス名：「野球バカ実況」
###### 以下サービスURL
https://www.yakyubaka-zikkyo.com/

######  以下Git Hub

https://github.com/GreatMuta514/baseball_app
## サービス概要
野球の試合を見ながらリアルタイムでチャットができます。
野球の試合の勝敗予想ができます。
野球ファンに試合観戦をより楽しんでもらえるサービスです！

**今日から日本シリーズが始まります！野球ファンの方は是非、試合を見ながら使ってみてください！**
## 使い方
### 試合前
試合前には、どんな試合になるかみんなで予想しましょう！
- 試合予想を投稿。
- みんなの予想をチェック。
- コメントで議論。
[![Image from Gyazo](https://i.gyazo.com/0aface578142523bf6ae52dabf312eb5.png)](https://gyazo.com/0aface578142523bf6ae52dabf312eb5)
### 試合中
テレビなどで試合を見ながら、みんなで話そう！
![https://i.gyazo.com/34c8c09a76e32c39a44231808bc7dcea.gif](https://i.gyazo.com/34c8c09a76e32c39a44231808bc7dcea.gif)
## ターゲットとなるユーザー
一言で言うと、とにかく野球が好きな人です。以下一点でも当てはまれば是非使ってみてください！
- 野球の試合を一人で見るのが物足りない人
- Twitterや掲示板サイト、YouTubeコメント欄などで、野球の話をつぶやいたり/見たりしている人
- 野球の試合を予想するのが好きな人
## このサービスが実現する課題解決
1. 人と話しながら外で野球を見るのは楽しいけど、家で一人で見るとそこまで盛り上がらない
**→毎日試合ごとにルームを作成し、野球好きが試合を見ながら楽しく話せるコミュニティを提供する。**

2. 現状、野球の掲示板サービスに多くの人が試合を見ながらコメントを投稿している。しかしリロードしないとメッセージが流れてこず使いにくい。
**→WebSocketsを用いた双方向通信をRailsで実現し、リロードしなくても流れるリアルタイムチャット機能を実装。**
3. 現状、多くの野球ファンが試合前の勝敗予想をTwitterやYouTubeのコミュニティに投稿してる。しかし予想後に試合を見ながらコミュニケーションを取る場所がなく、予想が的中したところで盛り上がらない。
**→本サービスでは「予想機能」と「試合を見ながらのチャット機能」を合わせて実装。「勝敗予想を投稿した後、試合を見ながらチャット」という流れで本サービスを利用すれば、ユーザー同士で「予想が的中したかどうか」も話し合える。また、プロフィール画像をクリックすれば予想履歴が表示されるので、「他ユーザーがどんな予想をしたか」を簡単に確認できる。**
4. 野球の掲示板サービスやYouTubeのコメント欄には、「結果論のくせにイキったコメント」を投稿するユーザーがたくさんいる。それがうざい。
**→本サービスは各ユーザーが「どれだけ予想を的中させているか」を確認できるため、そのユーザーが「どれくらいの野球に対する知見を持った上で、コメントしているのか」を確認できる。**

## 主な機能紹介
- リアルタイムチャット(試合を見ながら、みんなで盛り上がる！)
- 試合予想（試合前から勝敗予想を投稿し、みんなで盛り上がる！）
## 実装で大変だった点
#### ルーム別のリアルタイムチャット
ActionCableを用いた、ルーム別のリアルタイムチャット機能が大変でした。
ActionCableでルーム別のチャットを実装できている記事が日本語でも英語でも見当たらず、独力で研究しました。
以下のコードでは**ユーザーは同時に一つのサブスクリプションしか購読できないようにしています。**
もしこれをやらなければ、ユーザーが2つ以上のサブスクリプションを持てることになり、例えば「Room1というチャットルームにいるのに、Room2のチャットも表示されてしまう。」ということが発生してしまいます。

**ここは非常に難しかったので、別日Qitaに記事投稿しようと思います！**
```jsx
// channel.js

const channel = "RoomChannel"
const data = document.getElementById('data').dataset;
const chatroomId = data.chatroomId;
const userId = data.userId;
const userIdentifier = `"user_id":"${userId}"`;
// サブスクリプションのリスト
const subscriptions = consumer.subscriptions.subscriptions;

// 同じユーザーが2つ以上のチャンネルを同時に購読できないようにしている
if(subscriptions){
  subscriptions.map(function userUnsubscribe(subscription){
    if(subscription.identifier.includes(userIdentifier)){
      subscription.consumer.subscriptions.remove(subscription)
    };
  });
};

consumer.subscriptions.create(
  { 
    channel: channel, chatroom_id: chatroomId, user_id: userId
  },
  {
    connected() {
      // Called when the subscription is ready for use on the server
    },
  
    disconnected() {
      // Called when the subscription has been terminated by the server
      
    },
  
    received(data) {
      // データを受け取った時に以下を発動する
      document.getElementById('chat_container').insertAdjacentHTML('beforeend', data['chat']);
      scrollToBottom();
    }
  }
);
```
## 使用技術
**フロントエンド**
HTML
SCSS
JavaScript

**バックエンド**
Ruby3.1.2
Rails6.1.6

**テスト**
RSpec

**インフラ**
MySQL
AWS EC2
AWS S3
## ER図
[![Image from Gyazo](https://i.gyazo.com/86306de4d2663452feee54d17e9e607a.png)](https://gyazo.com/86306de4d2663452feee54d17e9e607a)