Day19 リファクタリング２

#体重登録
**calclateアクション/Before**
<img width="954" alt="スクリーンショット 2020-02-04 12.29.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/754bf188-50c8-4cf4-a50b-7f6518da1e95.png">
<img width="809" alt="スクリーンショット 2020-02-04 12.31.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/ec0d2ee1-0a40-061c-b391-b45b77a476e2.png">
**問題点**
一つ目の赤枠と同じコードが実はもう一つ別のアクションでも使われていて、重複している。
二つ目の赤枠では、本来redirect_toでいいのに、renderしておりそこでそのためにインスタンスが生成されるという無駄な処理が行われている。
三つ目の赤枠では、本来はrenderが正しい。
**calculateアクション/After**
<img width="815" alt="スクリーンショット 2020-02-04 12.36.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/ab72ccc0-28e1-d5a1-faa1-8f72d9306946.png">
大幅にコード量が減っただけでなく、共通項を一つのコードにしたことで修正が必要なときなどに直す部分が一つで良くなり、保守性が向上した。

**共通化したメソッド（Application controller）**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/03346414-0c1f-e817-cd8f-179061a0d370.png)

#身長・BMI登録
**Before**
今までだと、ビューでもし身長データがあれば、登録された体重からBMIを計算してそれをグラフに反映するというロジックにしており、profileページに行くたびにBMIが計算されグラフに反映される処理が行われるロジックになっていた。

コードの可読性も悪いし、なにより毎回無駄な処理がされるというのは望ましくないため、必要なときのみBMIが登録されるようにした。

具体的にはBMIが登録されるのは、
１　プロフィール編集から身長データを登録した時
２　身長データがある状態で体重を記録した時
の２パターンで、２はすでに実装されていたので、１を今回は作成した。

**UserコントローラUpdateアクション**
<img width="547" alt="スクリーンショット 2020-02-04 23.50.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/74da39a4-8cfe-d485-9360-79e665777632.png">
**Application Controllerメソッド**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/4fc3bed6-e909-95ef-5fec-ddbe965098e2.png)
もしユーザが身長データを入力してきたら、既存の体重データからBMIを計算しそれを登録するようにした。
なおupdateなので既存の体重データがなくてもエラーにはならない。
**その他**
上の修正をしている時に気付いたのだが、今までだと上記のようなコードになっていて、EmailやNameをからで送信すると一番下のrenderでeditページに戻り、そしてそこでは.errors.full_messageが表示されるのだが、もし身長データも空にしていると、renderの前に身長がからの場合にBMIをnilにする記述があるのに、画面ではエラーで更新されていないように見えるが、実はBMIは消えているというよくない仕様になっていた。
<img width="569" alt="スクリーンショット 2020-02-04 23.39.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/907c126a-eca7-e022-8535-409ce6a1cfb7.png">
それを下記のように、大前提として更新を先に持ってきて、その中でもし身長が空ならBMIをnilにするという風に順番を変えることで、対処した。
<img width="489" alt="スクリーンショット 2020-02-04 23.43.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/6878c57e-27be-918c-8a4f-325be2508d58.png">
※一番下のコメントアウトしている変数の部分を入れると、.errors.full_messageがなくなる。エラーメッセージが前提としているのはデータがないことだけど、ここで生成してrenderしているからエラーとみなされないのだろうか？


#LIKES LIKED
**Before**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/3a8a1318-f754-9533-eef2-41fb6c110d99.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/0da3a413-93b5-779d-7a51-e998975e9fc0.png)
**After**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/8b20894a-9458-15f7-f689-90b0680c6a99.png)
ユーザのアイコンを表示する部分、いいねの表示・作成・削除の部分と、そしてグラフ表示の部分がLIKES　LIKEDで重複していたため、既存のパーシャルで対応できるところはそれで対応した。いいねアイコンの表示及び作成・削除の部分のみ新たにパーシャルを作成した。
**ユーザーアイコンのパーシャル**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/7d1e9e70-6ce3-bdb4-f14b-0a2d4360d42f.png)
**いいねの表示・作成・削除のパーシャル**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/cbcc8553-ad37-0058-103e-8ba7f8733126.png)
**グラフのパーシャル**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/fdf9b666-1480-d15e-98ed-bb90a76bd7ba.png)

#【番外編】redirect_toとrender
**概要**
redirect_toは基本的にデータに更新が会った時に使われる。例えば登録・削除・更新などである。
一方でrenderはデータに更新がない時に使用する。例えばユーザが更新しようとしたけどエラーでデータに変更がなかった時などである。

**疑問**
だが、redirect_toを使えばわざわざ遷移先のページで必要となる変数などをアクションで生成せずに、その遷移先のページのアクションが生成してくれるので楽だと思う。わざわざrenderでまた変数を用意しなければいけない理由がわからなかった。
例えば下記の画像はグラフへの体重登録が失敗した時のrenderのメソッドであるが、遷移先で必要な変数を多く記述している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/5245042d-5e42-9321-88a7-9824d188f964.png)
一方もしこれをredirect_toにすれば、下記画像の遷移先ページを表示するeditアクションが変数を用意するので上の一見冗長なコードは不要となる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/51d6175c-4ccb-fba3-1339-b24ebf6caa21.png)
なのになぜわざわざrenderを使うのか。

**renderを使う理由**
答えから書くと、「ユーザが入力したデータを保つため」である。
redirect_toだと遷移先のページのアクションを介すので、すべてが初期値になってしまうが、renderはそこの変数をそのままviewにわたすことができるため、ユーザが入力した値をrender前で変数に入れておけば、遷移先でも表示することができるということである。

よってわざわざ遷移先で必要なデータを用意してまでrenderを使うのは、「よりユーザーフレンドリーな仕様」にするためである。