Railsのエラー『ActiveRecord::SerializationTypeMismatch』の解決方法

このエラーは、ActiveRecordがカラムのデータ型と保存されているデータの型が一致しないときに発生する。特に、JSONや配列の型を扱う際に発生しやすい。この記事では、エラーの原因と対処法を説明する。
目次
エラーの発生条件
以下のようなケースでこのエラーが発生する。
- カラムの型として
json
またはjsonb
を指定しているが、保存するデータが不適切 - シリアライズされたデータの型がカラムの型と異なる
- 古いデータが不適切な型で保存されている
エラーメッセージの例
このエラーは、例えば以下のようなメッセージで表示される。
ActiveRecord::SerializationTypeMismatch: can't load `Object`: was supposed to be a Hash, but was a String
原因の確認
カラムの型を確認するには、Railsコンソールで次のコマンドを実行する。
ActiveRecord::Base.connection.columns(:users).find { |c| c.name == "settings" }.sql_type
例えば、設定値がjsonb
型であるべきなのにstring
として保存されている場合、エラーが発生する可能性がある。
データの型を統一する
正しい型でデータを保存するように修正する。
user.settings = JSON.parse(user.settings) if user.settings.is_a?(String)
user.save!
マイグレーションでカラムの型を変更する
データ型が適切でない場合、マイグレーションを作成して型を変更する。
class ChangeSettingsToJson < ActiveRecord::Migration[6.0]
def change
change_column :users, :settings, :jsonb, using: 'settings::jsonb'
end
end
シリアライズを明示的に指定する
モデルにserialize
を指定すると、データを適切に扱えるようになる。
class User < ApplicationRecord
serialize :settings, JSON
end
古いデータを修正する
既存データの型が適切でない場合、データベースの値を修正する。
User.find_each do |user|
user.update(settings: JSON.parse(user.settings)) if user.settings.is_a?(String)
end
まとめ
- カラムの型とデータの型を一致させる
- データを適切に変換して保存する
- マイグレーションでカラムの型を変更する
- モデルに
serialize
を指定する - 古いデータを修正する
-
前の記事
PHPエラー『Fatal Error: Uncaught Exception』の解決方法 2025.04.16
-
次の記事
MariaDB 指定した単位のみの日時データの差分を取得する 2025.04.16
コメントを書く