0

Rails 3.2.13 アプリケーションを Ruby 1.8.7-p370 から Ruby 1.9.3-p385 にアップグレードしています。アップグレード後、データベースから取得したテキストで特殊文字が文字化けします。たとえば、"café" は "café" と表示されます。私のデータベースは、latin1 でエンコードされています。私はmysql2(0.3.11)を使用していますが、私のdatabase.yml見た目は次のようになります:

development:
  adapter: mysql2
  encoding: latin1
  database: my_db
  username: root
  host: localhost

(同じ問題は、同じデータベース構成を持つ本番環境でも発生しています。)

ActiveRecord がデータベースからテキストを取得するとき、指定した latin1 (または ISO-8859-1) ではなく、utf-8 であるかのようにデコードするようです。

この問題を診断するために、ActiveRecord をバイパスして、mysql2 を使用してデータベースに直接クエリを実行する Ruby スクリプトを作成しました。

require 'rubygems'
require 'mysql2'

client = Mysql2::Client.new(:host => "localhost",
                            :username => "root",
                            :database => "food52_development_production",
                            :encoding => "latin1")

result = client.query('SELECT title FROM recipes WHERE id = 12934')

puts result.first["title"]

ID 12934 のレシピには、タイトルに「カフェ」という単語が含まれています。1.9.3 でこのスクリプトを実行すると、正しくデコードされたテキスト (「カフェ」) が出力されます。:encodingオプションをに変更すると"utf-8"、文字化けしたテキスト (「カフェ」) が再び表示されます。

にブレークポイントを配置して、ActiveRecord::ConnectionAdaptersRails がどのエンコーディング構成で をどのように初期化しているかを確認しMysql2::Clientました。さすがに通過:encoding => "latin1"です。

それでも、Rails はどこかでテキストを utf-8 としてデコードすることを決定します。指定した latin1 エンコーディング構成を Rails に反映させるにはどうすればよいですか? よろしくお願いします。

4

1 に答える 1

1

1.9.3 の時点で、iconv は非推奨です。また、Rails 3 はすべての入力で UTF-8 エンコーディングを想定しています。

そうは言っても、いくつかの異なるオプションがあります。1 つ目はかなりハックですが、データを移行したくない場合は機能します。

iconv ライブラリは引き続きgemとして利用できます。これを使用して、アプリで必要に応じてこれらの変換を手動で行うことができます。

Airbnb のスタッフは、次のようなヘルパーを使用しています。

def self.convert_string_encoding(to, from, str)
  if "1.9".respond_to?(:force_encoding)
    str = str.dup if str.frozen?
    str.encode(to, from, :undef => :replace)
  else
    require 'iconv'
    Iconv.conv(to, from, str)
  end
end

変換を処理します。ビューのヘルパーにこれをスローする可能性があります。

移行の詳細については、こちらをご覧ください

問題は、Rails のデフォルトの UTF-8 をデータベースのエンコーディングに変換しようとする場合です。

おそらくもっと理にかなっているのは、既存のデータを UTF-8 に移行することです。

この記事はそれをかなりうまくカバーしているようです。

これが役立つことを願っています!

于 2013-03-20T17:07:34.523 に答える