Rubyのバージョンを2.7.0にあげてrake taskを実行したら見たことないエラーが出たので対処法をメモ。
Ruby...2.7.0
Rails...5.1.5
発生したエラー
NoMethodError: undefined method `new' for BigDecimal:Class
下記の記事によると、decimal型のカラムがあるインスタンスを取得しようとした時に発生するらしい。
RailsアプリをRuby 2.7.0で動かして分かったこと – PSYENCE:MEDIA
確かに今回取得使用しようとしたplayersテーブルを見ると、batting_averageカラムにdecimal型を使っている。
↓schema.rb
create_table "players", force: :cascade, do |t| t.integer "status", null: false t.decimal "batting_average", precision: 5, scale: 2 end
decimal型
可変長浮動小数点の値。
t.decimal "batting_average", precision: 5, scale: 2
この場合、有効桁数が5桁、少数点数が2桁。
pry(main)> Integer(2) => 2 pry(main)> BigDecimal(2) => 0.2e1 pry(main)> BigDecimal(2).to_i => 2
正確な演算処理が必要な場合はdecimal型を使う。
class BigDecimal (Ruby 2.7.0 リファレンスマニュアル)
MySQL :: MySQL 5.6 リファレンスマニュアル :: 11.2.2 固定小数点型 (真数値) - DECIMAL、NUMERIC
対処法
gem 'bigdecimal'
をインストールする
後からちゃんと調べて分かったのだけど、bigdecimalライブラリはRuby標準なので本来はgemを入れなくても使えるが、Ruby2.7以降でエラーが発生してしまうからgemでバージョンを明示的にしてあげる必要がある、ということかな?多分。
試したこと
とりあえずgemを入れてみる
いくつかの記事でバージョンを指定せよと書いてあったが、とりあえず一旦何も指定せずインストールして解決しないかを試してみた
↓Gemfile
gem 'bigdecimal'
$ bundle install
↓Gemfile.lock
bigdecimal (2.0.0)
最新のバージョンがインストールされた。
この状態だとまだ同じエラーが発生してしまうようだった。やはりバージョンを指定して(下げて)あげないといけないぽい。
↓Gemfile
gem 'bigdecimal', 1.4.2
$ bundle install
↓Gemfile.lock
bigdecimal (1.4.2)
これでrake実行したところ、今度はエラーが解消されました。
参考
GitHub - ruby/bigdecimal: Arbitrary-precision decimal floating-point number library for Ruby
Rails NoMethodError: undefined method new for BigDecimal:Class - Stack Overflow