前提・実現したいこと
Railsでモデルを作成しています。
モデルを保存しようとした際、以下のエラーメッセージが発生しました。
エラーを解消して、DBに保存できるようにしたいです。
発生している問題・エラーメッセージ
Encoding::CompatibilityError: incompatible character encodings: UTF-8 and ASCII-8BIT
該当のソースコード
一部、名前を書き換えています。
Model
1class Model_A < ApplicationRecord 2 # 論理削除使用 3 acts_as_paranoid 4 5 # 暗号化カラムの定義 6 attr_encrypted_options.merge!(algorithm: "aes-128-ecb", encode: false, insecure_mode: true, iv: "", key: :generate_key) 7 attr_encrypted :mail_address 8 attr_encrypted :contact_name 9 10 # リレーション 11 belongs_to :company_A, optional: true 12 13 # バリデーション 14 15 validates :company_A_id, 16 presence: true 17 18 validates :name, 19 presence: true, 20 length: { maximum: 100 } 21 22 validates :postal_code, 23 length: { is: 8 }, 24 format: { with: /\A[0-9\-]+\z/ }, 25 reduce: true 26 27 validates :address, 28 presence: true, 29 length: { maximum: 500 } 30 31 validates :phone_number, 32 presence: true, 33 length: { maximum: 13 }, 34 format: { with: /\A[0-9\-]+\z/ }, 35 reduce: true 36 37 validates :fax_number, 38 length: { maximum: 13 }, 39 format: { allow_blank: true, with: /\A[0-9\-]+\z/ }, 40 reduce: true 41 42 validates :mail_address, 43 length: { maximum: 200 }, 44 email: { allow_blank: true }, 45 reduce: true 46 47 validates :contact_name, 48 presence: true, 49 length: { maximum: 100 } 50 51 validates :note, 52 length: { maximum: 2000 } 53 54 validates :display_order, 55 presence: true, 56 numericality: { 57 only_integer: true, 58 greater_than_or_equal_to: 1 59 }, 60 reduce: true 61 62 validates :old_flg, 63 presence: true 64 65 66 def generate_key 67 key = crypt_key 68 final_key = "\0" * 16 69 key.length.times do |i| 70 final_key[i % 16] = (final_key[i % 16].ord ^ key[i].ord).chr 71 end 72 final_key 73 end 74 75end
schema
1 create_table "table_A", id: :integer, unsigned: true, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| 2 t.integer "company_A_id", null: false, unsigned: true 3 t.string "name", limit: 100, null: false 4 t.string "postal_code", limit: 8 5 t.string "address", limit: 500, null: false 6 t.string "phone_number", limit: 13, null: false 7 t.string "fax_number", limit: 13 8 t.string "encrypted_mail_address", limit: 200 9 t.string "encrypted_contact_name", limit: 100, null: false 10 t.string "note", limit: 2000 11 t.integer "display_order", null: false, unsigned: true 12 t.integer "old_flg", limit: 1, default: 0, null: false, unsigned: true 13 t.integer "updater_id", unsigned: true 14 t.datetime "created_at", null: false 15 t.datetime "updated_at" 16 t.datetime "deleted_at" 17 end
試したこと
コンソールで下記を行った所、タイトルのエラーが発生しました。
a = VehicleDealer.new(company_A_id: 1, name: "会社A", postal_code: "123-4567", address: "東京都新宿区西新宿2丁目8−1", phone_number: "090-1234-5678", contact_name: "担当者 ", display_order: 1) a.save!
文字コードを調べました。
[23] pry(main)> a.name.encoding => #<Encoding:UTF-8> [24] pry(main)> a.postal_code.encoding => #<Encoding:UTF-8> [25] pry(main)> a.address.encoding => #<Encoding:UTF-8> [26] pry(main)> a.phone_number.encoding => #<Encoding:UTF-8> [27] pry(main)> a.encrypted_contact_name.encoding => #<Encoding:ASCII-8BIT> [28] pry(main)> a.contact_name.encoding => #<Encoding:UTF-8>
a.encrypted_contact_nameだけ、ASCII-8BITになっていたため
UTF-8に揃えるように文字コードを変更してみました。
[35] pry(main)> a.encrypted_contact_name.force_encoding('UTF-8') => ";\xA9\xF7\xAF\u00166\xC9怬\xAA\x872N\xBBH" [36] pry(main)> a.encrypted_contact_name.encoding => #<Encoding:UTF-8>
すると、下記のようなエラーが発生しました。
Mysql2::Error: Incorrect string value: '\xA9\xF7\xAF\u00166\xC9...' for column 'encrypted_contact_name' at row 1
補足情報(FW/ツールのバージョンなど)
暗号化は下記記事の通りにやっています。
MySQLのAES_ENCRYPT/AES_DECRYPT互換の方式でActiveRecordの属性を透過的に暗号化/復号する - Qiita
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/11/12 00:01
2019/11/12 01:45