Rails MySQL データ型をdecimalにしているのに小数点を扱ってくれなくて困った話

# 目的

- DBに格納されている数値に少数の値を足そうとして詰まりまくったところをまとめる

# 困った箇所

1. viewファイルで表している入力formの少数の値が入力できない。
    - こちらで解決した→[HTML 少数入力時に「有効な値を入力してください」と出たときの話](https://qiita.com/miriwo/items/603cd7452d948161b6a6)
1. 入力してDBのカラムに保存しようとしてもカラムに反映されない。`save`でのエラーは出ない。
1. `rails console`で当該カラムに少数を入力し`save`するとDBのカラムに反映されるが、formから少数を入力しても足し算されない、整数の足し算はできる。

# 「viewファイルで表している入力formの少数の値が入力できない」の解決方法

- 下記の方法で解決した。
    - こちらで解決した[HTML 少数入力時に「有効な値を入力してください」と出たときの話](https://qiita.com/miriwo/items/603cd7452d948161b6a6)

# 「入力してDBのカラムに保存しようとしてもカラムに反映されない。`save`でのエラーは出ない。」の原因と解決方法

### 調査と原因

- 数値を保存するカラム`stady_time`のデータ型は少数を扱うために`decimal`にしている。
- 下記にカラム`stady_time`を作成したときのマイグレーションファイルを下記に記載する。

```rb
class AddStudyTimeHashTagToPosts < ActiveRecord::Migration[6.0]
  def change
    add_column :posts, :study_time, "decimal"
  end
end
```

- 原因はカラム作成時にデータ型"decimal"を設定するときにオプションで格納する数値の全桁数と少数部分の桁数のを指定する必要があったようである。

### 解決方法

- カラム`study_time`を削除して再度オプション付きで作成し直すか、現在存在する`study_time`カラムのデー型を設定し直すかの二通りがある。
- 今回は個人プロダクトであるが、デプロイして使用されているサービスで重要なカラムを一旦削除することはありえないため、データ型を設定し直す方法をとる。
- 下記の修正を加える

    ||修正前|修正後|修正可否|
    |---|---|---|---|
    |カラム名|study_time|study_time|修正しない|
    |データ型|decimal|decimal|修正しない|
    |データ型のオプション|指定なし|全桁数12桁 少数点以下桁数2桁|修正する|

- 下記にカラムのデータ型設定を修正する手順を記載する。
    1. 下記コマンドを実行してマイグレーションファイル(DBの仕様変更を命令するファイル)を作成する。

        ```terminal
        $ rails g migration change_study_time
        ```
    1. `db/migrate/`に存在するマイグレーションファイル`20200112011439_change_study_time.rb`に下記の記載を行う(`#`の行はコメントなので実際はなくても良い)
    
        ```ruby
        class AddPasswordToUsers < ActiveRecord::Migration[6.0]
          def change
            #カラムの変更なのでchenge_column :テーブル名, :カラム名, :データ型, :オプション(数値の全桁数), :オプション(数値の小数点以下の桁数、第二位まで欲しいので2とした)
            change_column :posts, :study_time, :decimal, precision: 12, scale: 2
          end
        end
        ```
    1. 下記コマンドを実行してマイグレート(DBにマイグレーションファイル通りの仕様変更を行う命令)を行う。
    
        ```terminal
        $ rails db:migrate
        ```
    1. もしマイグレーションファイルの記載を間違えてマイグレートしてしまったら下記の方法でマイグレート前の状態に戻す。
        - [Rails6 マイグレーションファイルの記載ミスでマイグレートしてしまったらrollbackを使おう](https://qiita.com/miriwo/items/9fac9f5e6dffb7427f80)
    1. 下記方法でカラムの方が正常に設定されているか確認する。
        - [Rails6 rails consoleからカラムのデータ型を確認する](https://qiita.com/miriwo/items/3e62491e05ba47d55e45)
        - 今回の場合Postモデルのstudy_timeカラムなので下記のコマンドになる。
            1. rails consoleを起動し下記コマンドを実行する。

            ```
            >Post.columns_hash['study_time'].type
            => :decimal
            ```

# 「`rails console`で当該カラムに少数を入力し`save`するとDBのカラムに反映されるが、formから少数を入力しても足し算されない、整数の足し算はできる。」の原因と解決方法

### 調査と原因

- rails consoleでの確認と切り分けにより足し算を行なっているコントローラファイルに問題があると感じた。
- 少数は表示できるのに足されないということはformから送られてきた値を数値に変換している箇所に間違いがあると予想した。
- 下記にpostコントローラの当該処理のメソッドを抜粋して記載する。

    ```ruby
    def update
      @post = Post.find_by(id: params[:id])
      @post.study_time += params[:study_time].to_i
      @post.save
      redirect_to("/posts/#{@post.id}")
    end
    ```

- `params[:study_time]`にはフォームで入力した少数値が入っている。`.to_i`で入力した文字列を数値に変更している。
- 整数を表現する場合は`.to_i`でも良いが、少数を扱い際は別の表現にしないといけない。

### 解決方法

- コントローラでフォームで入力した値を数値をして扱う処理で整数に変換してしまっているので少数も含む数値に変換してあげる記載をする。
- `.to_i`を`.to_f`とする。
- 下記に正しいコードを記載する。

    ```ruby
    def update
      @post = Post.find_by(id: params[:id])
      @post.study_time += params[:study_time].to_f
      @post.save
      redirect_to("/posts/#{@post.id}")
    end
    ```