「Mysql2::Error: Data too long for column」の原因(Rails)

【結論】

Mysql2::Error: Data too long for columnとは、DB側の文字数制限を超えたデータを保存しようとした際に発生するエラー

・DB側の制限なので、モデルなどにバリデーションを設定していないとしても、このエラーは発生する

・対応策は、DB側の制限を変更するか、モデルやフロントにバリデーションを設定して事前に食い止める

【目次】

【本題】

エラーの経緯

一定の文字数以上を登録しようとするとエラーになるバグが発生しました。

しかし、モデルに文字数制限のバリデーションは設定していません。

エラーメッセージを確認して見ると、以下のような内容でした。

ActiveRecord::ValueTooLong in ×××××:×××××Controller#update

Mysql2::Error: Data too long for column '×××××' at row 1: UPDATE `×××××` SET `×××××` = '×××××

原因:DB側の文字数制限

このMysql2::Error: Data too long for columnですが、マイグレーション実行時に指定した(あるいはデフォルト)最大幅を超えたデータを保存しようとした際に発生します。

なお、最大幅は以下のようにlimitで指定することが出来ます。

文字列のstring型とtext型、数値のinteger型とbinary型で指定が可能です。

create_table :products do |t|
      t.string :name, limit: 10
      t.integer :price, limit: 7
end

このエラーは、あくまでDB側の設定によるものなので、たとえモデルやフロントでバリデーションを設定していなかったとしても発生します。

対策1:DB側の文字数制限を変更

このエラーを発生しないようにするには、先ほどのlimitの値を変更して、許容できる文字数を増やす方法があります。

def change
  change_column :products, :name, :string, limit: 20
end

対策2:モデルやフロントにバリデーション設定

または、モデルやフロントにバリデーションを設定し、DB側への保存の処理が走る前に、保存が中断されるようにするのも方法です。

参考情報

【Rails・MySQL】MySQLのデータ型とRailsのマイグレーションファイルのデータ定義の対応まとめ - Qiita

【Ruby on Rails】Mysql2::Error: Data too long for column 'xxxxx' at row 1: - きゃまなかのブログ

NOT NULLなどの制約の設定 - Ruby on Rails入門