※2022年から技術系の記事は個人ブログに投稿しております。ぜひこちらもご覧ください→yamaday0u Blog
先日、商品購入アプリの開発途中でテストコードを実装していたところ、初心者的にでとんでもなくエラーに苦しめられたので、後学のために書き残します。
環境
Rails:6.0.3.4
MySQL:5.6.50
##謎のエラー:Invalid octal digit
RailsのgemであるRSpecを使ってテストコードの確認をしていたところ、以下のようなエラーが出ました
bundle exec rspec spec/models/order_item_spec.rb
SyntaxError:
アプリ名/spec/factories/order_items.rb:8: Invalid octal digit
phone_numbr { 09012345678 }
^~
Invalid octal digit
は直訳すると「無効な8進数」という意味です。
テスト用に設定していた電話番号「09012345678」の2番目の9が無効な8進数でエラーしているよ、ということらしいです。
エラーの原因
エラーの原因を調べたところ、Rubyでは、0から始まる数値は8進数として解釈されるそうです。
8進数は0〜7の数字で構成されるので、8や9があるとエラーになります。
今回の場合、テスト用の電話番号が、0から始まるために8進数の数値として解釈され、その後ろに8進数では存在しない9が出てきたために、「invalid octal digit(無効な8進数)」というエラーが出てきたというわけです。
解決策:データ型を変更(integer→string)
今回の商品購入アプリでは、データベースに保存する電話番号をinteger型に設定していたため、上記のような「0から始まるために8進数の数値」として解釈されていまいました。
そこで、rails g migration
コマンドを使ってマイグレーションファイルを作成し、電話番号のデータ型をstring型にする変更を行いました。
rails g migration change_data_phone_number_orders
作成したマイグレーションファイルに以下のように記述し、rails db:migrate
して完了です。
def change
change_column :orders, :phone_number, :string
# ordersはテーブル名、phone_numberがカラム名、stringが新しいデータ型
end
rails db:migrate
ターミナルで再度bundle exec rspec spec/models/order_item_spec.rb
したところ、無事テストが通りました。
データ型をintegerから変えないで解決する方法もあるとは思うのですが、調べがつかなかったので今回はこれで解決しました。
プログラミングの経験が浅い方は、電話番号のデータ型はstringにしておく方が無難だと思います。
RSpecについては以前記事を書いたことがありますので、是非読んでみてください。
RSpecの導入&関係の深いgemについて(Qiita)
参考資料
invalid octal digit エラーが起きたとき(datetimeで起きて泣いたのでメモ)(Qiita)
Rubyのエラーを整理(初級者向け) - Speaker Deck