2013-02-27 7 views
2

Я в процессе обновления старого устаревшего приложения Rails 2.3 к чему-то более современному и запущенному в проблему с кодировкой. Я прочитал все существующие ответы, которые я могу найти по этой проблеме, но у меня все еще возникают проблемы.Ошибка кодирования с Rails 2.3 на Ruby 1.9.3

Rails вер: 2.3.17 Рубиновые версии: 1.9.3p385

Мои таблицы MySQL являются по умолчанию набор символов: utf8, сверка: utf8_general_ci. До 1.9 я использовал оригинальный камень mysql без инцидентов. После обновления до 1.9, когда он получен ничего с utf8 символов в ней бы получить это хорошо документированный проблема:

ActionView::TemplateError (incompatible character encodings: ASCII-8BIT and UTF-8) 

Я переключился на mysql2 драгоценный камень для его превосходной управляемостью, и я больше не вижу исключения, но вещи, безусловно, не кодирующие правильно. Например, то, что появляется в БД как строка Repoussé визуализируется с помощью Rails, как Repoussé, “Boat” выглядит как “Boat†и т.д.

Несколько больше деталей:

  • Я вижу те же результаты, когда я использую Драйвер ruby-mysql как водитель.
  • Я добавил encoding: utf8 строки в каждой записи в моем database.yml

Я также добавил следующее мое environment.rb:

Encoding.default_external = Encoding::UTF_8 
Encoding.default_internal = Encoding::UTF_8 

Она пришла мне в голову, что я, возможно, некоторое несоответствие где latin1 записывается старой версией приложения в поля utf8 базы данных или что-то в этом роде, но все символы отображаются правильно, если смотреть в клиенте командной строки mysql.

Заранее благодарим за любые советы, высоко ценим!

ОБНОВЛЕНИЕ: Теперь я считаю, что проблема заключается в том, что мои данные utf8 принудительно выполняются через двоичное преобразование в latin1 по пути из db, я просто не уверен, где.

mysql> SELECT CONVERT(CONVERT(name USING BINARY) USING latin1) AS latin1, CONVERT(CONVERT(name USING BINARY) USING utf8) AS utf8 FROM items WHERE id=myid; 
+-------------+----------+ 
| latin1  | utf8  | 
+-------------+----------+ 
| Repoussé | Repoussé | 
+-------------+----------+ 

У меня есть encoding набор для utf8 в database.yml, любые другие идеи, где это может быть из?

+0

Просто из любопытства, чем ваша HTML страница кодирования? Является ли оно явно задано 'utf-8'? – mudasobwa

+0

Хорошо, да это: '' –

+0

Чтобы найти источник проблемы более точно, я бы предложил вам ' Logger.debug' ваши данные из вашего шаблона, модели, везде. Полагаю, это не драйвер 'mysql', искажающий ваши данные. – mudasobwa

ответ

6

Я, наконец, понял, в чем моя проблема. В то время как мои базы данных были закодированы с помощью utf8, приложение с оригинальным драгоценным камнем mysql вводило текст latin1 в таблицы utf8.

Что меня отбросило, так это то, что результат работы клиента mysql comand выглядит корректно. Важно проверить, что ваш терминал, поля базы данных и все клиенты MySQL работают в utf8.

Клиент MySQL работает по умолчанию latin1. Вы можете обнаружить, что она работает в, выдавая этот запрос:

show variables like 'char%'; 

Если установка правильно для utf8 вы должны увидеть:

+--------------------------+----------------------------+ 
| Variable_name   | Value      | 
+--------------------------+----------------------------+ 
| character_set_client  | utf8      | 
| character_set_connection | utf8      | 
| character_set_database | utf8      | 
| character_set_filesystem | binary      | 
| character_set_results | utf8      | 
| character_set_server  | utf8      | 
| character_set_system  | utf8      | 
| character_sets_dir  | /usr/share/mysql/charsets/ | 
+--------------------------+----------------------------+ 

Если они не выглядят правильно, убедитесь, что установлено следующее в [client] разделе файла конфигурации my.cnf:

default-character-set = utf8 

Add добавьте следующие строки в разделе [mysqld]:

# use utf8 by default 
character-set-server=utf8 
collation-server=utf8_general_ci 

Перед перезагрузкой клиента обязательно перезапустите демон mysql, а затем проверьте.

ПРИМЕЧАНИЕ. Это не изменяет кодировку или сортировку существующих баз данных, просто гарантирует, что любые созданные новые базы данных будут установлены по умолчанию в utf8 и что клиент отобразит его в utf8.

После этого я увидел символов в клиенте mysql, который соответствовал тому, что я получал от драгоценного камня mysql2. Я также смог проверить, что этот контент был latin1, перейдя на «encoding: latin1» временно в моем database.conf.

Один чрезвычайно удобный запрос, чтобы найти вопросы, использует обугленную длину, чтобы найти строки с многобайтными символами:

SELECT id, name FROM items WHERE LENGTH(name) != CHAR_LENGTH(name); 

Есть много сценариев там конвертировать latin1 содержимые utf8, но то, что работало лучше всего для меня было демпинг все базы данных, как latin1 и начинку содержимое обратно в качестве utf8:

mysqldump -u root -p --opt --default-character-set=latin1 --skip-set-charset DBNAME > DBNAME.sql 

mysql -u root -p --default-character-set=utf8 DBNAME < DBNAME.sql 

Я резервное копирование мой основной БД, а затем сбрасывали в тестовую базу данных и Вери как сумасшедший, прежде чем перейти к исправленной БД.

Мое понимание заключается в том, что перевод MySQL может оставить некоторые вещи желательными с некоторыми более сложными символами, но поскольку большинство моих многобайтовых символов - довольно распространенные вещи (знаки акцента, кавычки и т. Д.), Это отлично подойдет для меня.

Некоторые ресурсы, которые оказались неоценимы при сортировке все это:

1

Вы говорите, что все выглядит нормально в клиенте командной строки, но, возможно, кодировка символов вашего терминала не настроена на отображение UTF8? Чтобы проверить терминал OS X, нажмите «Terminal»> «Настройки»> «Настройки»> «Дополнительно»> «Кодировка символов». Кроме того, проверьте с помощью графического инструмента, такого как MySQL Query Browser, по адресу http://dev.mysql.com/downloads/gui-tools/5.0.html.

+0

Спасибо за предложение! Моя кодировка терминала установлена ​​в UTF8. –