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

f:id:ryoutaku_jo:20190903225220p:plain

【結論】

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入門

《今日の学習進捗(3年以内に10000時間に向けて)》

先日の手動テストで見つかったバグの修正を行なったが、軽微かつ数も多く無かった為、本日で概ね全てのバグ修正を終えることが出来た。
リリースまで3日間残っているが、ユーザビリティの問題が山積しているのと、自動テストが手薄な箇所が散見される為、その辺りの対応を行っていきたい。

テストについては、現状システムとリクエストのみを拡充しているが、手動テストにて大量に文字列を入力すると500エラーが発生するという事象もあった為、モデルも用意した方が良いと考えている。
優先度は他のテストに比べると低いが、先々で着手していきたい。

なお、本日は通常より多い8件のプルリクのレビューを行なったが、いずれもファイルチェンジが5つ程度で収まっていたので、比較的短時間でレビューを終えることが出来た。
改めてプルリクの粒度が細かい方が、レビューが捗ると実感した。
このあたりは、ガイドラインなどを緩くでも良いので作成して、延々と同一ブランチで作業を進めることが無いように工夫した方が良いかもしれないと考えている。

学習開始からの期間 :270日
今日までの合計時間:2537h
一日あたりの平均学習時間:9.4h
今日までに到達すべき目標時間:2466h
目標との解離:71h
「10,000時間」まで、

残り・・・「7463時間!」