【ポートフォリオ解説】date-matchの全てがこれで分かる！

#初めに
この記事は、date-matchを詳細に解説した記事です。
この記事とGitHubのREADMEとの違いは次のとおりです。

```
この記事：date-matchをより詳細に解説して、情報を網羅的に把握ができる。
README：date-matchの概要を把握ができる。
```
date-matchの辞書的な位置付けとして、この記事を作成しました。
気になる項目だけでもご覧頂けたら、幸いです。
※随時、項目を追加予定です。

#アプリ概要
あなたの行きたい場所やイベントを提案・検索することで、デート相手を効率よく見つけることができるマッチングアプリです。
主に、次の3点ができます。

```
1. 行きたい日時やプランなどを添えて、提案ができる
2. 住所やキーワードなどで検索、行きたい日時が近い順などで並び替えができる
3. ダイレクトメッセージを通じて、招待ができる
```

これらが出来ることで、既存のマッチングアプリにはない、このアプリ特有のメリットが3点あります。

```
1. 自分の行きたい場所に共感してくれている人、行きたい日時が合う人から、お相手を効率よく探すことができる
2. 自分の行きたい場所や日時ありきで検索ができるので、お相手を効率よく探すことができる
3. マッチング時点で、行きたい場所や日時が共有されているので、デートにお誘いしやすい
```
[![Image from Gyazo](https://i.gyazo.com/cb3e8eee8a24637a2abe7d22bb08f18f.gif)](https://gyazo.com/cb3e8eee8a24637a2abe7d22bb08f18f)

※大変申し訳ありませんが、現在は非公開です。
~~以下のURLにて公開中です！ゲストログイン機能ですぐに閲覧ができます~~
~~https://www.date-match.net/~~

GitHubのURLはこちらです！
https://github.com/sdkk1/date-match


#作成背景
**過去に自分が困った経験**と**既存のマッチングアプリにも「こういう機能があればいいのに」**という思いから作成しました。

作成に至るまでの流れを簡潔にまとめると、次のとおりです。

```
自分が困った経験　→　既存サービスを使用して、改良点を思いつく　→　作成に至る
```

具体的には下記の通りです。

```
1. 行きたい場所やイベントがあるけど、一緒に行く人がいない
2. 既存のマッチングアプリでは、自分の行きたい場所や日時が合う人を探しにくい
```

##1.行きたい場所やイベントがあるけど、一緒に行く人がいない
過去にこんな経験がありました。

`「ここのカフェ、めっちゃオシャレでケーキも美味しそうだし、行ってみたいなあ〜。
　でも、雰囲気的に一人だと入りにくいし、ましてや男同士なんて以ての外だな。
　かと言って、誘える女友達もいないしなあ〜。どうしようかなあ〜・・・」`

結局、行かず仕舞いです。笑
この時、**行きたい場所があるけど、一緒に行く人がいない人**というもどかしさを感じました。

##2. 既存のマッチングアプリでは、自分の行きたい場所や日時が合う人を探しにくい
`「だったら、マッチングアプリで探してみるか！」`

そう思い、いざ開いてみたところ、

`「あー、たくさんのユーザーから気になる人にいいね！して、マッチングしないと誘うことが出来ないじゃん。
　せっかくマッチングしても、相手も行きたいと思っているか分からないし、日程も合うか分からない。
　もっと簡単に、自分の行きたい場所や日時が合う人を探せるアプリはないかなあ〜・・・」`

何十種類か使ってみましたが、**男女問わず、自分の行きたい場所や日時を提案できて、かつそれを検索や並び替えできるもの**はありませんでした。

`「だったら、自分で作ってみるか！」`

そんな想いから、date-matchが誕生しました。

#使用技術
* __フロントエンド__
  * __HTML__
  * __CSS ( BEM・FLOCSS )__
  * __Sass 2.1.2__
  * __Bootstrap 4.5.3__
  * __JavaScript__
  * __jQuery 4.4.0__

* __バックエンド__
  * __Ruby 2.5.7__
  * __Ruby on Rails 5.2.3__

* __テスト__
  * __RSpec 4.0.0.beta2 ( モデルテスト、リクエストテスト、 システムテストを約190examples )__
  * __Factory Bot 4.10.0__
  * __RuboCop 2.3.2__

* __開発環境__
  * __Docker 19.03.13__
  * __Docker Compose 1.27.4__
  * __Visual Studio Code 1.44.2__

* __本番環境__
  * __AWS ( VPC, EC2, S3, RDS, Route53, ACM, ALB )__
  * __PostgreSQL 11.5__
  * __nginx 1.12.2__
  * __Unicorn 5.7.0__
  * __CircleCI 2.0__
  * __Capistrano 3.14.1__

#インフラ構成図
[![Image from Gyazo](https://i.gyazo.com/fc575966a5000e9aea3f9177439e61a3.png)](https://gyazo.com/fc575966a5000e9aea3f9177439e61a3)

#機能一覧
##1.提案機能
|番号|機能|説明|
|:----:|:------------:|:--------------------------:|
|  ①  |提案登録（CRUD）|提案を新規登録、一覧表示、詳細表示、編集、削除できる
|  ②  |オートコンプリートによる住所検索（Google Maps API)|名称や店名を入力すると、オートコンプリートで検索候補を補完し、その住所が表示される
|  ③  |地図表示（Google Maps API）|ユーザーが登録した住所から、その地点の地図を表示する
|  ④  |天気予報表示（Open Weather Map API）|ユーザーが登録した住所から、その地点の天気予報を表示する
|  ⑤  |ハッシュタグ付け（acts-as-taggable-on）|提案にハッシュタグを付けることができて、キーワード検索ができる
|  ⑥  |お気に入り登録・削除（Ajax）|非同期通信でお気に入りに登録・削除ができる
|  ⑦  |行きたい！リクエスト申請・取消（Ajax）|非同期通信で行きたい！リクエストを申請・取消ができる
|  ⑧  |閲覧履歴保存|ユーザーが閲覧した提案を履歴として保存する
|  ⑨  |閲覧数カウント（impressionist）|提案詳細が閲覧された数をカウントする
|  ⑩  |コメント投稿・削除（Ajax）|非同期通信で提案にコメントを投稿・削除できる
|  ⑪  |星5段階評価(Raty.js)|コメント投稿と合わせて、提案を星5段階で評価できる

##2.ユーザー機能
|番号|機能|説明|
|:----:|:------------:|:--------------------------:|
|  ①  |ユーザー登録（CRUD）|ユーザーを新規登録、一覧表示、詳細表示、編集、削除できる
|  ②  |ログイン|登録されたユーザーのメールアドレスとパスワードでログインができる
|  ③  |ゲストログイン|ユーザー登録をせずに、ログインができる
|  ④  |足跡数カウント（impressionist）|ユーザー詳細が閲覧された数をカウントする
|  ⑤  |いいね！申請（Ajax）|非同期通信でいいね！申請ができる
|  ⑥  |ダイレクトメッセージ（Ajax）|非同期通信でマッチングしたユーザー同士のダイレクトメッセージができる

##3.共通機能
|番号|機能|説明|
|:----:|:------------:|:--------------------------:|
|  ①  |写真の複数枚登録・編集・削除（Active Storage）|写真を複数枚登録、編集、削除できる
|  ②  |3D フリップスライダー（Swiper）|登録された写真をフリップスライダーで閲覧できる
|  ③  |通知|行きたい！リクエストされた時、コメントされた時、いいね！された時、メッセージが届いた時に通知が来る（未確認通知がある場合は、マークを表示）
|  ④  |AND検索（ransack）|各検索条件でAND検索ができる
|  ⑤  |検索結果の並び替え（ransack）|検索結果を指定した条件で並び替えできる
|  ⑥  |ページネーション（kaminari,一部Ajax）|表示内容を複数ページに分割できる

#ER図
[![Image from Gyazo](https://i.gyazo.com/e2c2a1e3abd2ab8839c727b70c615c8e.png)](https://gyazo.com/e2c2a1e3abd2ab8839c727b70c615c8e)

#工夫した点
##1.ユーザー調査
### `アンケート調査`
- 約30名にdate-matchを使ってもらい、ユーザー目線でのサービスの使用感（操作のしやすさ、見やすさ 等）を調査
- 良かった点、悪かった点を自由記述してもらい、今後の改善点を洗い出す
- 性別、プログラミング経験、マッチングアプリ利用経験などの個人属性によるばらつきを極力なくすように満遍なく調査

以下のリンク先に調査結果をまとめました！
[date-match アンケート調査結果](https://docs.google.com/presentation/d/14lzIfpN_Kx4_ba2EvlSe-qxqHdli0Cc6jijH6SUiVd4/edit?usp=sharing)

※以下に、調査結果を一部抜粋しました。
[![Image from Gyazo](https://i.gyazo.com/8cfc89d631cfe5129047fe32e849b6b6.png)](https://gyazo.com/8cfc89d631cfe5129047fe32e849b6b6)
[![Image from Gyazo](https://i.gyazo.com/567fbba0ac7102698f684c30734b82d5.png)](https://gyazo.com/567fbba0ac7102698f684c30734b82d5)
[![Image from Gyazo](https://i.gyazo.com/f07f1472a5e0be574e60e985be620b3c.jpg)](https://gyazo.com/f07f1472a5e0be574e60e985be620b3c)

##2.フロントエンド
### `デザイン全般`
- 『ゼロからはじめるデザイン』( 著者：北村　崇 )を読んで、デザインを一から学習
- 既存の類似サービスを研究し、良いと思った要素を取り入れる

### `配色`
- メインカラーは、サービスのコンセプト（気軽な出会い）から連想される**イエロー**に設定
- ベースカラーは、メインカラーの明度を高くしたものにして、コントラストをとる
- フォントカラーは、メイン・ベースカラーと相性の良いワインレッドに設定

[![Image from Gyazo](https://i.gyazo.com/25ef4237beac470da50b39286157acf8.png)](https://gyazo.com/25ef4237beac470da50b39286157acf8)

### `操作性`
- サイドバーメニューをスクロール追従させ、リンクしやすいように工夫
- アイコンを多用し、直感的に理解しやすいように工夫
- クリックできる箇所は、ホバーエフェクトをつけて、明確化

[![Image from Gyazo](https://i.gyazo.com/4b15964668b25d292e0f485834366524.gif)](https://gyazo.com/4b15964668b25d292e0f485834366524)

##3.バックエンド
### `オートコンプリートによる住所検索機能`
- Google Maps APIを用いて、名称や店名を入力すると、オートコンプリートで検索候補を補完し、その住所が表示される機能を実装
- 提案を入力する時に、わざわざ住所を検索する手間が省ける

[![Image from Gyazo](https://i.gyazo.com/9c1172c5502261d71f185290e72d8389.gif)](https://gyazo.com/9c1172c5502261d71f185290e72d8389)

### `天気予報表示機能`
- Open Weather Map APIを用いて、入力された住所からその地点における天気予報が表示される機能を実装
- お出かけする時に、天気予報をわざわざ確認する手間が省ける

[![Image from Gyazo](https://i.gyazo.com/32ced9db07c8e0367e7a956150243a9c.jpg)](https://gyazo.com/32ced9db07c8e0367e7a956150243a9c)

### `豊富な検索・並べ替え機能`
- ユーザーの提案を名称、提案者、住所、キーワードで検索できる
- Datespotモデルのカラムによる並び替えだけでなく、関連するモデル（Favoriteモデル、Commentモデル、Listモデル）のレコード数による並び替えもできる

[![Image from Gyazo](https://i.gyazo.com/f02eb64b076dfdd9e94953b6b94d3a0c.png)](https://gyazo.com/f02eb64b076dfdd9e94953b6b94d3a0c)

[![Image from Gyazo](https://i.gyazo.com/2d49dbf8397c2da6e06ef84d4906598e.gif)](https://gyazo.com/2d49dbf8397c2da6e06ef84d4906598e)

[![Image from Gyazo](https://i.gyazo.com/8e7c27dd4840b45216cb990620a95099.gif)](https://gyazo.com/8e7c27dd4840b45216cb990620a95099)

### `非同期通信（Ajax）を用いてユーザーストレスの軽減`
- コメント投稿・削除機能やページネーションなどに非同期通信（Ajax）を用いてユーザーストレスの軽減を実現

[![Image from Gyazo](https://i.gyazo.com/fb5305414120d4eda60b0f8bbea2c58e.gif)](https://gyazo.com/fb5305414120d4eda60b0f8bbea2c58e)

[![Image from Gyazo](https://i.gyazo.com/95aff8a8c1b1bb87c9bbd7fbf07ca3ee.gif)](https://gyazo.com/95aff8a8c1b1bb87c9bbd7fbf07ca3ee)

##4.インフラ
### `AWSへのデプロイ`
- AWS ( VPC, EC2, S3, RDS, Route53, ACM, ALB )を使用した本番環境の構築

[![Image from Gyazo](https://i.gyazo.com/15bf22954a8d6f1cbed9b98b9086f8fd.png)](https://gyazo.com/15bf22954a8d6f1cbed9b98b9086f8fd)

### `CircleCIによる自動テスト・自動デプロイ`
- CircleCIによる自動テスト・自動デプロイ環境を構築し、開発効率を向上
- デプロイ前にバグを検知できるように、Rspec、RuboCopによるテストが通らないとデプロイできない環境を構築

[![Image from Gyazo](https://i.gyazo.com/b7fc0bf274981f38c0b19760c3503183.png)](https://gyazo.com/b7fc0bf274981f38c0b19760c3503183)

#苦労した点
##1.Google Maps APIを用いた地図表示
### `苦労したポイント`
- 入力された住所を座標値に変換するところで苦戦
- 詳細な住所（例えば、東京都港区芝公園４丁目２−８ 等）が上手く変換されず、地図が正しい位置に表示されなかった

### `解決方法`
- Geocoding APIを用いて入力された住所を座標値に変換することで解決

その時の過程をQiitaにまとめています！
[Qiita記事：【地図表示】Google Maps JavaScript APIとGeocoding APIを用いてユーザーが登録した住所から地図を表示する！](https://qiita.com/sdkk-rails/items/08dcc780fe070fcf35b6)

### `学んだこと`
- 外部APIの利用方法
- Geocoding APIを用いた座標値変換

##2.OpenWeatherMap APIを用いた週間天気予報表示
### `苦労したポイント`
- API応答で返ってきた値の取得

### `解決方法`
- Chrome拡張機能である「Advanced REST Client」を用いて、どんな値が返ってくるか確認しながら必要な情報を取得

その時の過程をQiitaにまとめています！
[Qiita記事：【週間天気予報表示】OpenWeatherMap APIを用いてユーザーが登録した住所から週間天気予報を表示する！（無料）](https://qiita.com/sdkk-rails/items/3589afefda4169976965)

### `学んだこと`
- API応答で返ってくる値を確認しながら、必要な情報を取得する方法

##3.関連するモデルのレコード数による並び替え
### `苦労したポイント`
- gemのデフォルトにはない機能を追加する必要があった
- 参考となる情報がほとんどなく、自分で考える必要があった

### `解決方法`
- `:counter_cache`オプションを用いて関連するレコードの数を集計できるようにした
- Active Recordコールバックを用いて関連するレコードの値を更新できるようにした

その時の過程をQiitaにまとめています！
[Qiita記事：【ransack】関連するモデルのレコード数による並び替え](https://qiita.com/sdkk-rails/items/0d36c58d6c8acaae38db)

### `学んだこと`
- 実装したい機能を細かく分解して、1つ1つ形にしていく過程
- それをドキュメント等を参考に、自らで考えること

#今後の実装予定
* __フロントエンド__
  * __レスポンシブ対応__
  * __SPAの導入によるUI/UXの向上__

* __バックエンド__
  * __提案されたデートのカテゴリー分け機能__
  * __現在地からの距離検索機能__
  * __迷惑ユーザーのブロック機能__

* __インフラ__
  * __ECS(EKS)でのデプロイ__
  * __インフラのコード化__

* __その他__
  * __Railsのバージョンアップ__
  * __テストコードの充実__

#終わりに
date-matchの解説記事は、以上です。
ここまで読んで頂き、ありがとうございました！！