Ruby 1.9, проблема кодировки символов MySQL - PullRequest
0 голосов
/ 02 декабря 2011

Наше приложение Rails 3 должно иметь возможность принимать иностранные символы, такие как ä и こ, и сохранять их в нашей базе данных MySQL, у которой свой набор символов_tf8.

Одна из наших моделей запускает проверку, которая используется для удаления всех несловарных символов в ее имени перед сохранением. В Ruby 1.8.7 и Rails 2 было достаточно следующего:

def strip_non_words(string)
  string.gsub!(/\W/,'')
end

Это убрало плохих персонажей, но сохранило такие вещи, как 'ä', 'こ' и '3.' Однако в новых кодировках Ruby 1.9 это утверждение больше не работает - теперь оно удаляет те символы, а также другие, которые нам не нужны. Я пытаюсь найти способ сделать это.

Изменение gsub на что-то вроде этого:

def strip_non_words(string)
  string.gsub!(/[[:punct]]/,'')
end

позволяет строке пройти нормально, но затем база данных выдает следующую ошибку:

Mysql2::Error: Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation

Запуск строки через Iconv, чтобы попытаться преобразовать ее, вот так:

def strip_non_words(string)
  Iconv.conv('LATIN1', 'UTF8', string)
  string.gsub!(/[[:punct]]/,'')
end

Результат this error:

Iconv::IllegalSequence: "こäè" # "こäè" being a test string

Я в основном здесь, на коне. Кто-нибудь знает способ сделать то, что мне нужно?

1 Ответ

1 голос
/ 05 декабря 2011

Это оказалось немного интересным исправлением.

Я обнаружил, что в Ruby есть регулярное выражение, которое я мог бы использовать, но только для строк ASCII. Поэтому мне пришлось преобразовать строку в ASCII, запустить регулярное выражение, а затем преобразовать его обратно для отправки в БД. Конечный результат выглядит так:

def strip_non_words(string)
  string_encoded = string.force_encoding(Encoding::ASCII_8BIT)
  string_encoded.gsub!(/\p{Word}+/, '') # non-word characters
  string_reencoded = string_encoded.force_encoding('ISO-8859-1')
  string_reencoded #return
end

Оказывается, вы должны кодировать вещи отдельно из-за того, как Ruby обрабатывает изменение кодировки символов: http://ablogaboutcode.com/2011/03/08/rails-3-patch-encoding-bug-while-action-caching-with-memcachestore/

...