【個人開発】「遠距離恋愛」をしている人のためのカップルアプリを開発しました！

# はじめに

こんにちは、[@aka_aka40058677](https://twitter.com/aka_aka40058677?s=21&t=t8A1WLrcaWUnGrE06BtfYQ)と申します。
私自身プログラミング学習中の未経験エンジニアであり、技術的な内容などは誤りを含む可能性があります。
そのため、おかしな記述などがあればコメント等で教えていただけたら幸いです🙇‍♀️

# 作成したアプリ

**アプリ名：[遠結び](https://enkyori-enmusubi.com)**
⚠️2024年1月をもちまして、アプリの公開を終了させていただきました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3106207/c4d3aa9b-a59e-a20e-1df3-50183437df4e.png" width = "800px">

サービス URL：https://enkyori-enmusubi.com
GitHub URL：https://github.com/akane-aoki/enmusubi

## 開発の背景

このサービスを開発したきっかけは、他でもない、**私自身が遠距離恋愛を長く経験してきた**からです。
なぜわざわざ遠距離恋愛をしているのか、私にも分かりません。遠距離恋愛が得意なわけでもないのに、なぜかいつもいつも、いつの間にか遠距離恋愛になってしまっているのです。

遠距離恋愛を始めたての私は、「**会いたいと思ったときに会えない寂しさ**」や「会いたいけど、会いたいと言うと鬱陶しく思われそう」といった苦しさに苛まれていました。
そこで、会えない間にもオンラインでゲームをしたり、ポケットWi-Fiが一瞬で通信制限になるくらい長時間ビデオ通話をしたりしていました。

そんなとき、いいアプリはないかと「遠距離恋愛　アプリ」とググってみたのですが、**ハートに溢れたコテコテのカップルアプリや、ただのスケジュール共有アプリ**などしかヒットしませんでした。

私は、「**カップルアプリらしからぬシンプルな、遠距離恋愛ならではの機能があるサービスが使いたいのに…！**」と思ったのです。

それならば、**遠距離恋愛のためのサービスを自分で作るしかない**！！と思い立ち、このサービスを作成しました。

## サービス概要

このサービスは、**恋人と２人だけのクローズドSNS**になります。

**「遠結び」の主要な機能**は以下のとおりです。
- 次会える日までのカウントダウン機能
- 会えていない日数に応じたごほうび設定機能
- 会えない間にがんばることの登録機能
- がんばったことの投稿機能
- お互いが行き来した回数をカウントし、総移動距離を表示する機能

ちなみに、レスポンシブ対応しているため、**スマホでもパソコンでも使用することができます**。

## サービスの使い方

:::note info
前提として、このサービスを使うには、ユーザー登録が必要となります。
各々がユーザー登録をした後、恋人登録をすることになります。
:::

<img src="https://i.gyazo.com/603fef2b9d1a54db55ec2b478848eba2.gif" width="1000">

ログインをすると、以下のようなダッシュボードが表示されます。
ここで、主要な情報は見ることができます。
<img src="https://i.gyazo.com/a1bf863bffa7aac91d31cb304ce1dd9b.png" width="1000">

この画面から、各機能の詳細ページに遷移することができます。

# 工夫した点
## 1.総移動距離を表示する機能

以下のように、２人の総移動距離と、東京からおよそどこまでの距離に相当するのかを知ることができます。
<img src="https://i.gyazo.com/d2ed85dd0524e074be8cef5b49ea9d17.gif" width="200">
これは、
- 今まで会った日の登録回数
- それぞれの自宅の郵便番号から算出された２点間距離

を元に値を算出しています。

実装にあたり、RailsのGemである「**geocoder**」と、**Google Maps API**を使用しました。

geocoderは、住所や郵便番号などを入力すると、緯度と経度を取得したり、２点間の距離を算出することができます。（とても便利！）
郵便番号ではなく住所を入れた方が正確な位置が算出できます。ただ、その分ユーザーにおける入力のハードルが高くなってしまう可能性を危惧したことと、機能としてそこまでの正確性が必要ではないと考えたため、郵便番号を登録してもらう形にしました。

**geocoderだけだと正確な住所を取得できない場合がある**ため、今後の機能拡張に備えるためにもGoogle Maps APIで補っています。

##### 【参考にした記事等】

https://kobacchi.com/rails-auto-generate-googlemaps-from-address/

https://github.com/alexreisner/geocoder


## 2.恋人登録機能

実装において最も悩んだのが、この恋人登録機能です。なぜか？
参考になる記事が非常に少なかったからです。
クローズドSNSのサービスを作成した方の記事がなかなか見つかりませんでした…。

というわけで、グループ招待機能などを参考にしながら実装を進めたのですが、結果的にシンプルな方法で作成することにしました。

こちらが「遠結び」の**ER図**です。
<img src="https://i.gyazo.com/36981b6d85d21fb512d2e48df49cb360.png" width="500">

#### 招待方法
1. まず、ユーザー作成時に、乱数で`invitation_digest`（招待コード）が勝手に作成されて、usersテーブルに保存されます。
2. 自分が招待する場合は、その招待コードを恋人登録画面で表示し、恋人に招待コードを教えます。
3. 招待される側の恋人は、教えてもらった招待コードを恋人登録画面で入力します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3106207/b95339e3-c0aa-c47b-645a-2c78da653dc5.png" width="200">
<img src="https://i.gyazo.com/5ef1898a52c30d7552a11cadebbe68dd.png" width="200">

以下、`invites_controller.rb`の抜粋です。
```ruby:app/controllers/invites_controller.rb
  def edit
    @user.invitation_digest = ""
  end

  def update
    @user = User.find(current_user.id)

    if params.present?
      @partner = User.find_by(invitation_digest: params[:user][:invitation_digest])
      if @user.update(relationship_id: @partner.relationship_id)
        redirect_to invite_path, success: t('defaults.message.invited')
      else
        flash.now['danger'] = t('defaults.message.not_invited')
        render :edit, status: :unprocessable_entity
      end
    else
      flash.now['danger'] = t('defaults.message.not_invited')
      render :edit, status: :unprocessable_entity
    end
  end
```

##### 【参考にした記事等】
招待機能はこの記事とは別の実装方法にしましたが、ER図等はかなり参考にさせていただきました。

https://qiita.com/matsu1226/items/782e84df9c88452369b7

## 3.その他のこだわりポイント

技術からは少し外れてしまうのですが、個人的なこだわりポイントをちょこっとだけ紹介させてください…！

#### ジェンダーレスなアプリにしてみた
- `性別の登録をしない`
- `「彼氏」「彼女」といった文言を使わない`
- `ハートやピンクなどのカップルアプリっぽさを無くしたシンプルなデザイン`

これに関しては、保健室の先生をしてきたことで出来上がった価値観や、単純に「カップル＝ハート、ピンク」みたいな固定観念がなんとなく好きではないのと、そういったものを使っていると私自身が気恥ずかしくなってきてしまうからです。

カップルアプリなのにジェンダーレスと言うと、相反するように感じる方もいらっしゃるかもしれませんが、やはり多様性は大事にしたいと思うのです。

# 主な使用技術
### バックエンド
- Ruby 3.2.0
- Ruby on Rails 7.0.4
- PostgreSQL

### フロントエンド
- JavaScript
- TailwindCSS 3.2.4
- daisyUI 2.50.0

### インフラ
- heroku
- Amazon S3

### その他
- Google Maps API（Geocoding API）

## 技術選定について
私が通っているプログラミングスクールRUNTEQにおいて、カリキュラムはRailsがメインとなっているため、使い慣れているRailsで作成しました。（**フルで仕事をしながら開発をしていたため、できるだけ最短で作成するためにも、技術はシンプルにしました。**）
TailwindCSSは慣れるまでは手こずりましたが、**daisyUIを導入して自分好みにカスタマイズすることで、簡単におしゃれにできる**のでおすすめです。個人的には**レスポンシブ対応が簡単にできる**ので、開発していて非常に楽しかったです。

# 開発期間
MVPリリースと本リリースまで、それぞれ約１ヶ月間かかったため、開発期間は約２ヶ月間です。
私は普通に公務員として仕事をしていたため、夜や休日中心に開発していました。

# おわりに
まだまだ改善点はたくさんありますが、今回初めて自分で0からサービスを作りあげ、またこうして初めて技術記事を投稿することができました。これはエンジニアを目指すにあたり小さな一歩にすぎませんが、今後も学習を継続し、よりよいサービスになるよう改良していきたいと思います。

また、遠距離恋愛はつらいことだけでなく、自分磨きをするチャンスになったり、会えたときの喜びが大きかったりと、良いこともたくさんありました。世界中の遠距離恋愛をしている方々が、毎日を少しでも楽しく過ごせるよう願っています。

この記事が、少しでも誰かのお役に立てば大変幸いです。
拙い記事でしたが、最後までお読みいただきありがとうございました！