【共同開発】欲しいものを買う優先度をランキング形式で提示するサービス「HoshiMe」をリリースしました！

# はじめに
早速ですが質問です。衝動買いをして後悔した経験はありませんか？

私はよく後悔しています。。
ずっと欲しかったものがあったにも関わらず、違うものを衝動買いしてお金を使ってしまい、本当に欲しかったものを買うためのお金がなくなってしまったことがありました。

そんな悩みを解決するために開発したのが、欲しいものを買う優先度をランキング形式で提示するサービス **『HoshiMe』（ほしみぃ）** です。

https://hoshime.herokuapp.com

# 使用技術
**バックエンド**
- Ruby 2.6.6
- Rails 6.1.4

**フロントエンド**
- TailwindCSS
- JavaScript(jQuery)
- Chart.js


# 主なサービス内容
### 欲しいもの登録ページ
ユーザ登録なしで欲しいもの3つ登録できるように実装しました。
<img width="1280" alt="three_items" src="https://user-images.githubusercontent.com/76583053/147766601-ca4ff008-4095-4ded-a01c-9dc9312e3119.png">

### ランキングページ
欲しいものを登録すると、以下のランキング形式で買う優先度が表示されます。また、ランキング上位３つ分の計算データをレーダーチャートを使って差が分かるように表示しています。
![スクリーンショット 2022-01-14 22.07.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1629690/289beb01-fc3b-25dc-1343-6946579f1fc9.png)

# こだわったポイント

### ゲストユーザ機能
 HoshiMeでは、できる限りたくさんのユーザの方々に、まず触って頂きたいという思いから、「はじめる」を押した時点でゲストユーザとしてログインされる仕様になっています。

```bash
  TRANSACTION (0.1ms)  BEGIN
  User Load (4.9ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1  [["LIMIT", 1]]
=> #<User:0x00007fe3bd20af00
 id: 108,
 name: "ae2b4e",
 email: "guest_ae2b4e@example.com",
 crypted_password: "$2a$10$/3SasIg85bnveT0IK/VIIOvEoAQ09QBK7XjrO5mvIs.BozatxJpp2",
 salt: "b9E3njyFrvUAkHuXmzvW",
 uuid: "448fb42e-51df-4a35-bf8f-45c28cbe0a08",
 created_at: Sat, 15 Jan 2022 14:46:11.513789000 JST +09:00,
 updated_at: Sat, 15 Jan 2022 14:46:11.513789000 JST +09:00,
 is_valid: true,
 role: "guest",
 reset_password_token: nil,
 reset_password_token_expires_at: nil,
 reset_password_email_sent_at: nil,
 access_count_to_reset_password_page: 0>
```

また、ユーザ新規登録したときにゲスト時に作成したデータをユーザ新規登録時にそのまま引き継ぐ仕様になっています。

<a href="https://gyazo.com/b4b6c977c5a785a19feb13a14e6b6c02"><img src="https://i.gyazo.com/b4b6c977c5a785a19feb13a14e6b6c02.png" alt="Image from Gyazo" width="950"/></a>

### アイテム一括投稿フォームの実装

入力フォームを複数用意し、submitボタンが押されたらフォームの内容をまとめて保存できるように実装しました。Form Objectで定義している`items`でフォームヘルパーの`fields_for`を使ってアイテムの情報を下記のようなハッシュ形式で受け取ります。

```ruby
"form_item_collection"=>{"items_attributes"=>{
"0"=>{"name"=>"Apple Watch", "degree"=>"60", "start_date"=>"180", "finish_date"=>"180", "price"=>"50000"},
"1"=>{"name"=>"リング", "degree"=>"30", "start_date"=>"30", "finish_date"=>"360", "price"=>"31000"},
"2"=>{"name"=>"キーボード", "degree"=>"70", "start_date"=>"360", "finish_date"=>"10", "price"=>"21000"}}}
```

そしてこの送信された一つずつのアイテムの`user_id`に`current_user.id`を付与して一括で保存する仕組みを作成しました。

### jRangeを使った範囲選択フォーム

フォームヘルパーを使用して、レンジ入力をしたいときは下記のように`range_field`を使います。

```ruby
<%= f.range_field :degree, min:"0", max:"100" %>
```

しかしこのままでは目盛りがないので、どれくらいの範囲を選択しているのか分かりづらいです。

![https://i.gyazo.com/989f447ddec1af7b8a582ce55692f870.png](https://i.gyazo.com/989f447ddec1af7b8a582ce55692f870.png)

目盛りをつけるために[jRange](https://nitinhayaran.github.io/jRange/demo/)というjQueryというライブラリを導入しました。

![https://i.gyazo.com/8affecc2604e8a762d1029f14e2e870a.gif](https://i.gyazo.com/8affecc2604e8a762d1029f14e2e870a.gif)


### ランキング機能
欲しいものを保存すると同時に保存した値を使ってランキングに必要な計算をしています。
その部分について簡単に説明します。

素直に入力された各パラメータ（欲しい度、いつから欲しい？、いつまでに欲しい？、値段）を合算してランキングにすると、値段の値（0~100,000）が大きすぎて値段のランキングみたいになってしまうので、各パラメータを変換します。
以下は「欲しい度」を計算するコードです。

```ruby
  # data にはユーザが入力した値が入る
  def calculate_degree(data)
    case data
    when 0..20
      degree_value = 2 # 欲しい度が 0~20 なら2に変換
    when 21..40
      degree_value = 4 # 同様に 21 ~ 40 なら4に変換
    when 41..60
      degree_value = 6
    when 61..80
      degree_value = 8
    when 81..100
      degree_value = 10
    end
    degree_value * 0.4
  end
```
このように各パラメータを５分割にし**２、４、６、８、１０**に変換します。
計算の最後に出てくる**×0.4**の係数ですが、これはそのパラメータの重要度によって値を変えています。
重要度が高いものから順に、

1. いつまでに欲しい？ : 0.8
2. いつから欲しい？ : 0.6
3. 欲しい度 : 0.4
4. 値段 : 0.2

欲しいものを登録する際の「いつまでに欲しい？」が一番ランキングに影響度が高く、「値段」は一番影響度が小さいことになります。

このように各パラメータを換算して係数をかけたものを合計し降順にしたものがランキングとなります。
# 共同開発の目的
私たちが共同開発をやった目的は大きく分けて次の３つです。

- 実務に入る前に共同で開発する時の流れや、雰囲気を知ること
- メンバー間でコミュニケーションを取りながら協力してひとつのものを作るという経験をすること
- GitやGitHubなどをより使えるようになること

今回3人で開発したのですが、難しい技術を使って実装するとか、大きなアプリを作るとかではなく、みんなで協力しながら楽しくやることを念頭に置いて取り組みました。

# 最後に
Twitter : sayo https://twitter.com/sayo_saru
今回のチーム開発を通して、誰がみても理解できるPRを書くこと、チームメンバーのPRを丁寧にレビューすることの大切さを痛感しました。毎週行っていたチーム開発会議で、本音で自分の考えていることを言い合えるメンバーだったので、とても楽しく開発ができました。
ありがとうございました。

Twitter : ワタル https://twitter.com/wataru_pgm
コンフリを起こした時の対処法、プルリクの書き方、チームが上げたプルリクをレビューするため、チェック用のブランチを作成して、挙動を実際に確かめるなど、たくさん繰り返し、多くのことを学ぶことができました。
新年の年明けと同時にHoshiMeをリリースすることができ、チームHoshiMeと使っていただいたユーザの方々に感謝です！

Twitter : たけむー https://twitter.com/takemuu_pote
今回初めて共同開発をやってみて、楽しかったというのが率直な感想です。
アイディア出しから始まり、画面遷移図とER図作成、実装してリリースまで３人で議論を重ねながら一緒にやり切ることができたのはとても良い経験になりました。
上記で述べた目的も達成でき、目標としていたあけおめリリースもできたので満足しています。

今回この3人で一緒にやれて本当に良かったと思います。
また機会があればやろうと思います。

最後まで読んでいただきありがとうございました。



**今回作ったアプリ**

https://hoshime.herokuapp.com/

**あけおめリリースツイート**

https://twitter.com/takemuu_pote/status/1476931175981596679?s=21