Day16 BMI表示機能と目標設定機能

#BMI表示機能
**完成後**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/12a80bf6-7644-28b9-4e81-fca14c1fb858.png)

**概要**
ダイエットアプリであるならその基準となるBMIも可視化するのはいいんじゃないかと思い、取り入れることにした。BMIも体重と日付と同様、グラフに起こすことで体重・日付と対応するようにした。

**ビュー**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/dfdfb883-73f2-c15f-c368-47ac339614e2.png)
ユーザが身長データを登録している場合のみ、BMIを計算し変数に格納。
そしてそのBMIはユーザのグラフテーブルつまり、体重日付とともにレコードに登録される。
一番下では、グラフに入れるデータとして日付とBMIをPluckで抽出した変数を定義している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/d5d3b49f-5630-1d76-e89d-691fa6ad901c.png)
身長データがある人はBMI入りのグラフを、そうでない人は通常の体重と日付のグラフを表示する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/c223463c-24ab-8011-447a-a09aefa03b24.png)
複数のデータのあるグラフは、chartkick公式に書き方の紹介があったのでそれにならった。

#BMI/身長リセット機能
コントローラのアクションにはdestroybmiという登録したBMIと身長情報をリセットする機能もオプションで用意しておいた。もちろんプロフィールページの身長を空欄で更新することによりBMIも身長も全てリセットされるが、わかりづらい操作方法であると思ったため別途用意した。
**完成後**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/4675dbfc-90d0-911b-2d99-45927b2049c7.png)
**コントローラ**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/548c7ff6-e043-20ef-d180-cbb43ef49ab2.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/11f86fbc-eae4-543a-b364-dfe7899133e5.png)
BMIデータが登録されるのは身長データがある時なので、身長データがあれば実行されるようにした。もちろん削除ボタンの出現の必要な要素は身長データがあることなので通常であればクリックされることはないが、直接PATCHリクエスト（削除としているがリソースが削除されるわけではなくコラムの更新でnilにしているだけ）を送られた場合にもそこでフィルターをかけた。
またBefore_actionでログインしていること、正しいユーザ（paramsとcurrent_userが同一）の確認も踏んでいる。

#目標設定機能
**完成後**
<img width="861" alt="スクリーンショット 2020-01-31 12.03.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/112850a8-711d-18a7-0204-a71183cb1419.png">
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/dcb2a4d0-5f40-3b1c-d7e4-604ee7ede16a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/9335d370-e643-3441-d8af-72d8c38ecb27.png)
**概要**
目標体重を設定しているユーザに対しては、最新の日付の体重と目標体重の差を示すようにした。
また目標体重が達成された場合、遊び心でユーザ名の横に表示される目標達成アイコンももらえるようにした。（他にはAdminマークや非表示ユーザマークがすでにある）
**ビュー**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/c2ff4b18-bd2f-c3ca-7585-f6ca9bcbcccf.png)
userdataという変数にはparamsから取得したユーザ情報が入っている。またそれがcurrent_userと同一であるという条件も加えたのは、差分の表示を自分自身に留めるためである。
三つ目のgraphが空でない時も条件にしたのは、そうしないと何もグラフデータがないのに目標設定をしている場合、graphデータを前提にしているメソッドがこどごとくエラーになってしまうためである。（メソッドではグラフデータを前提にしているのでエラー回避）
グラフデータがなくても.nil?だとFalseになるので、一応箱自体はあるみたい。
**コントローラ**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/bbaa65e7-58b7-916b-aa56-70b1e743b1d9.png)

目標達成アイコンを表示するかしないかは、Userのgoalコラムの真偽値で判断する仕組みになっている。
コントローラでは目標達成をしたユーザかつ、goalアイコンを持っていないユーザのみに対してアイコンを付与したいため、目標体重と最新体重の差分が０以下であることと、goal属性がtureでないことを条件とした。

もちろんアイコンをゲットするボタンは目標達成をしないと出現しないが、直接URLを投げられてしまうことも考えられるのでここでもフィルターをかけている。

また差分を計算する際にifでuserの体重データがあるかどうかをチェックしているのは、万が一URLを直接投げた人が体重データを登録していない場合エラーが出るのでそれを回避するためである。

#その他
**BigDecimal**
Rubyではfloat型の計算だと正確な計算ができない仕様で、例えばこんな風になってしまう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/a51f5191-756d-2c6e-2832-13da3d4c1a4e.png)
そこで正確な計算をするためにはBigDecimalを使えば正確に計算することができる。BigDecimalは文字列を引数に扱うのでto_sでString型に変換する必要がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/19828cba-d4d5-51ac-926a-e22638fa3b47.png)

**Herokuのタイムゾーン変更**
Herokuにデプロイした本番環境だけ、Date.todayが一日ずれていることに気がついた。
調べるとそれはタイムゾーンが日本じゃないからで、したがって変更してあげれば解決した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/99b84501-ea3f-fd47-638c-a095a283d037.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/557da953-e0c9-45c5-62d4-21a6fe7d5b70.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/b86fed4e-9852-87e9-66a6-b6fe62097603.png)
app名は特に指定しなくてもいい模様。
参考https://qiita.com/ikemura23/items/52ab8a5d260c7ee4d42b