🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
ASCII

ASCIIは、米国規格協会(ANSI)が制定したコンピューターの情報交換のための文字コードの一つ。アルファベットや数字などを1文字当たり7ビットで表します。英数字を表示する文字コードの中で最も高い互換性を持ち、多くの通信機器に利用されています。

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

UTF-8

UTF-8は8ビット符号単位の文字符号化形式及び文字符号化スキームです。データ交換方式、ファイル形式としては、一般的にUTF-8が使われる傾向があります。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Q&A

解決済

1回答

13043閲覧

Encoding::CompatibilityError: incompatible character encodings: UTF-8 and ASCII-8BIT

snyt45

総合スコア7

ASCII

ASCIIは、米国規格協会(ANSI)が制定したコンピューターの情報交換のための文字コードの一つ。アルファベットや数字などを1文字当たり7ビットで表します。英数字を表示する文字コードの中で最も高い互換性を持ち、多くの通信機器に利用されています。

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

UTF-8

UTF-8は8ビット符号単位の文字符号化形式及び文字符号化スキームです。データ交換方式、ファイル形式としては、一般的にUTF-8が使われる傾向があります。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

0グッド

0クリップ

投稿2019/11/11 12:03

編集2019/11/11 12:05

前提・実現したいこと

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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

encrypted_contact_name を string もしくは text でmigrateしてませんか? binaryでなければならないのでは?

force_encoding('UTF-8') は中身がどんなbyte列であってもそのままutf-8とみなします ということですが、MySQLが受け取った時そのbyte列がUTF-8でありえないということででたエラーではないかと思います。

投稿2019/11/11 15:07

winterboum

総合スコア23567

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

snyt45

2019/11/12 00:01

確かstringでmigrateしていると思います・・・ 再度見直してみます!!
snyt45

2019/11/12 01:45

migrationで型をstringからblobに変更したところ、保存されるようになりました!ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問