RailsとMySQLのテストで日付がうまく扱えない

目次

概要

Railsのテストで、データベースとしてMySQLを使っています。

ある時、色々と実装をして追加でテストを書いた後に、テストを実行して見ると次のようなエラーが出てテストに失敗しました。

ActiveRecord::StatementInvalid: Mysql2::Error: Incorrect datetime value: ‘2018-02-13 07:32:52 UTC’ for column

ここではこのエラーの解決法について紹介します。

環境

  • Ruby on Rails 5.1.4
  • MySQL 5.6 5.7 8.0

環境を見ればわかりますが、ほぼ全てのMySQLでエラーが発生しました。

原因

エラーメッセージを見れば分かるのですが、これはSQLとして渡された日付の値が不正であるということを表しています。

私は、この日付をテストのfixturesとしてyamlファイルの中で、次のようにして生成していました。

one:
  ...
  date: <%= Time.zone.now %>
  ...

カラム名などは適当に読み替えてください。

このようにして生成した日付がMySQLの日付として不正な値であると思われたようです。

解決方法

解決方法を調べて見ると、MySQLのSQLモードを変更すれば良いということが書かれていました。

しかし、テストのためだけにMySQLの設定を書き換えるのは気が進まないのと、実行する環境のSQLモードに左右されるというのはよろしくないということで他の方法を探しました。

そもそも、MySQLの日付として値がふさわしくないということなので、MySQLの値として適切なものをRails側で生成するようにすれば解決です。

このようなことを念頭に調べて見ると、Rubyの方でデータベースに適した日付を生成する方法がありました。

それは元にfixturesを次のようにしました。

one:
  ...
  date: <%= Time.zone.now.to_s(:db) %>
  ...

文字列を生成するto_sメソッドの引数に:dbを指定します。

これで、データベースフレンドリーな日付を生成してエラーが発生しなくなりました。