【個人開発】アレンジ飯を共有するサービスArrangy(アレンジー）をリリースしました

### サービス概要
コンビニ商品や外食店の料理を使用したアレンジ飯を共有するサービスです。
URL: https://arrangy.jp/
Github: https://github.com/kazu-2020/arrangy
<img src='https://user-images.githubusercontent.com/64774307/120076985-1a858800-c0e3-11eb-9bbb-0030767b667f.png'>

### サービスを制作した背景
　一人暮らしをしていた際、食事を外食店やスーパー、コンビニの惣菜で済ませることが多くありました。そのため、次第に同じ物を食べてばかりの食生活になり、結果、好きで食べていた物を「食べ飽きてしまった」という経験がありました。また、昨今のコロナによって外食が難しくなり、「食の選択肢」そのものが少なくなっているという印象を受けていました。
　そこで、これらの問題を解決する手段として私がサービスを通じて提案したのが「アレンジ飯」という選択肢です。アレンジ飯とは既に出来上がっている料理に一手間加えることで別の料理に変えることを言います。アレンジ飯の良さを一人でも多くの方に知ってもらいたいと思い、Arrangy(アレンジー)を制作しました。



### サービスの使い方
注: タブレットサイズではデザインが崩れます!

まずはトップページです。
ログインしなくても、投稿されたアレンジ飯を確認することができ、ページ上部には新しく投稿されたアレンジ飯をカールセルを用いて表示しています。
また、ページをスクロールして頂くとアレンジ飯の一覧が表示され、「いいね数」の多い順に表示されるようになっています。
[![Image from Gyazo](https://i.gyazo.com/13af6adcfdb817de9d867f268ad5761c.gif)](https://gyazo.com/13af6adcfdb817de9d867f268ad5761c)

ログイン後は「新規投稿、コメント機能、いいね機能」を使用することができます。

新規投稿する際は、下記の項目を設定してもらうようになっています。
・　画像投稿　・・・　アレンジ前の写真とアレンジ後の写真を１枚ずつ選択する。
・　タイトル
・　投稿内容・・・　材料や作り方を記入する
・　アレンジ度　・・・　アレンジの度合いを「ちょい足し」「激変」の2択から選択する。
・　おすすめ度　・・・　5段階で設定する。
[![Image from Gyazo](https://i.gyazo.com/de6ccfd9a862dad4b5d20530a8c5e388.png)](https://gyazo.com/de6ccfd9a862dad4b5d20530a8c5e388)
[![Image from Gyazo](https://i.gyazo.com/9b6460a76967b6510107ca73384ff6ef.png)](https://gyazo.com/9b6460a76967b6510107ca73384ff6ef)

いいねボタンは各投稿ページで選択することができます。
[![Image from Gyazo](https://i.gyazo.com/7286e32b86941bacb85fe489220bcccd.png)](https://gyazo.com/7286e32b86941bacb85fe489220bcccd)
いいねした投稿はお気に入り一覧に追加されます。
[![Image from Gyazo](https://i.gyazo.com/516b27ba25b01bd19cc5a0a9253cb9de.png)](https://gyazo.com/516b27ba25b01bd19cc5a0a9253cb9de)

### 苦労したこと
####①RailsからVueに画像ファイルどうやって渡すの問題
Railsのみ使用していた時は、`form_with`がよしなにやってくれていたので、何も意識せずに画像ファイルを扱うことができました。しかし、フロントにVueを使用した場合はよしなにやってくれていた箇所を自分で実装しなければなりません。
そこで今回はVueからRailsへ`エンコードしたデータURL`を渡し、Rails側で`デコード`を行うことでこの問題を解決しました。しかし、この実装は次の問題で泣く泣く変更することになりました(笑)。

####②本番環境で投稿にめちゃくちゃ時間かかる問題
　①では`gem carrierwave`を使用し、画像ファイル自体は`s3`に保存する形にしていました。開発環境で確認した際は問題なかったのですが、本番環境で投稿時間を測定すると画像１枚を含めて投稿するのに`4s`もかかっていました...
[![Image from Gyazo](https://i.gyazo.com/0dfe5ce7051a8fa0555629ed0aebb751.png)](https://gyazo.com/0dfe5ce7051a8fa0555629ed0aebb751)
　色々調べた結果、herokuを使用する際はブラウザからs3に直接アップロードする方法が推奨されていました。この方法を採用したところ、画像2枚を含めて投稿するのにかかる時間を`1s`まで抑えることができました。
[![Image from Gyazo](https://i.gyazo.com/323a205568d33fb02cfdfb8028e54da1.png)](https://gyazo.com/323a205568d33fb02cfdfb8028e54da1)

####③TwitterのOGPが動的に変更されない問題
フィードバックを元に各投稿をtwitterでシェアできる機能を実装する際に発生した問題です。これはVue側でmetaタグが動的に変更されるようにしていても、twitterのクローラーがJavaScriptを実行してくれないのが原因でした。この問題を解決するために`Nuxt`を使用するといる案もありましたが、既にサービスがほとんど完成していた状態でしたので別の案を採用しました。
それが`twitterクローラーがアクセスしてきた場合のみ、静的なHTMLを返す`という手法です。
まず判別方法ですが、twitterクローラーの場合は、`Twitterbot/1.0`という情報が`ユーザーエージェント`に含まれます。そのため、routingのオプションにある`constraints`を使用して下記のようなルーティングを設定してあげることで実現しました。

```ruby
  get '/arrangements/:id', to: 'crawlers#show', constraints: { user_agent: /Twitterbot\/1.0/ }
```
後は、gem metatagsを使用してmetaタグを動的に変更してあげることで解決しました。
[![Image from Gyazo](https://i.gyazo.com/4c1f6ea481f6bd6aa6c33bdb343a9888.png)](https://gyazo.com/4c1f6ea481f6bd6aa6c33bdb343a9888)

### 工夫した点
####①画像をアップロードする際、トリミングを行えるようにする
サイトに表示される際にアスペクト比1:1で表示されるのですが、cssのcontainやcoverでは不自然な画像に整形されることがあったので、ユーザーにアスペクト比1:1でトリミングした画像を投稿してもらうようにしました。
[![Image from Gyazo](https://i.gyazo.com/7a9483e5280249f9e19337b88f928657.gif)](https://gyazo.com/7a9483e5280249f9e19337b88f928657)

####②各投稿にアレンジ前の写真を載せるようにする
投稿一覧を閲覧する際、使用した商品が一目で分かるようにしました。
[![Image from Gyazo](https://i.gyazo.com/b654607bac5382689932c9c16dbe53e4.png)](https://gyazo.com/b654607bac5382689932c9c16dbe53e4)

### ER図
<img src="https://user-images.githubusercontent.com/64774307/120371875-66d5ff80-c351-11eb-8af5-2bad1be49f84.png">

### インフラ構成
<img src="https://user-images.githubusercontent.com/64774307/120373968-e9f85500-c353-11eb-8a5c-40ffff80c357.png">

### さいごに
今回初めてのサービスを無事にリリースすることができました。
個人的にはサービスのアイディア出しに非常に苦労したので、就活用の１ポートフォリオではなく、大変思い入れのあるサービスになりました。
今後も引き続き、改善していきたいと思っているのでフィードバックなど貰えると幸いです。

是非、ご家族やご友人にアレンジ飯を振る舞ってみてください！