Rails 3 - Как обработать PG Ошибка неполного многобайтового символа - PullRequest
2 голосов
/ 07 февраля 2012

В приложении Rails 3.2 (Ruby 1.9.2) я получаю следующие ошибки

Произошла ошибка PGE в обновлении mobile_users #:

неполный многобайтовый символ

Это ошибки Postgres, но я получаю похожую ошибку SQLIte при тестировании в dev и режимах тестирования

Параметры, вызывающие эту ошибку (токен намеренно опущен)

  * Parameters: {"mobile_user"=>{"quiz_id"=>"1", "auth"=>"xxx", "name"=>"Joaqu\xEDn"}, "action"=>"update", "controller"=>"mobile_users", "id"=>"1", "format"=>"mobile"}

Это приходит как запрос JSON HTTP Put, и действие обновления, имеющее к этому отношение, выглядит следующим образом

  # PUT /mobile_users/1
  # PUT /mobile_users/1.xml
  def update
    @mobile_user = current_mobile_user
    @mobile_user.attributes = params[:mobile_user]

    respond_to do |format|
      if @mobile_user.save
        format.html { redirect_to(@mobile_user, :notice => 'Mobile user was successfully updated.') }
        format.json  { head :ok }
        format.mobile  { head :ok }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.json  { render :json => @mobile_user.errors, :status => :unprocessable_entity }
        format.mobile  { render :json => @mobile_user.errors, :status => :unprocessable_entity }
        format.xml  { render :xml => @mobile_user.errors, :status => :unprocessable_entity }
      end
    end

  end

В приведенных выше параметрах указана строка, которая нарушает правила: "Joaqu \ xEDn", что вполне допустимо. дело в том, что мне нужно обрабатывать все наборы символов на любом языке.

Полагаю, мне нужно было бы использовать библиотеку iconv, но для этого мне нужно было бы определить набор символов для преобразования в UTF8, и я понятия не имею, как это сделать.

Я также получаю недопустимую последовательность байтов в UTF-8 для "name"=>"p\xEDa "

Ответы [ 2 ]

5 голосов
/ 07 февраля 2012

Это:

"Joaqu\xEDn"

является версией "Joaquín" в кодировке ISO-8859-1, поэтому это недействительный UTF-8, и ваши базы данных вправе жаловаться на это. Если возможно, исправьте ваши мобильные клиенты для использования UTF-8 в JSON; если вы не можете этого сделать, то вы можете исправить кодировку с помощью:

params[:mobile_user][:name].force_encoding('iso-8859-1').encode!('utf-8')

на сервере. Проблема с его исправлением на сервере заключается в том, что вам нужно угадать, что такое входящая кодировка, и ваше предположение может быть неверным. Нет способа надежно угадать кодировку для конкретной строки, есть rchardet , но она не работает с последними версиями Ruby и, похоже, была заброшена; Вы можете исправить этот драгоценный камень для работы с современным Ruby. Есть еще несколько библиотек с предположениями, но все они, похоже, тоже заброшены.

Текст JSON всегда, по определению , Unicode и UTF-8 кодируются по умолчанию:

3.  Encoding

   JSON text SHALL be encoded in Unicode.  The default encoding is
   UTF-8.

Любые клиенты, отправляющие вам JSON, которого нет в UTF-8, имеют IMO, потому что почти все предполагают, что JSON будет UTF-8. Конечно, где-то может быть заголовок кодировки, который определяет ISO 8859-1, или, возможно, заголовки говорят UTF-8, даже если это ISO 8859-1.

4 голосов
/ 07 февраля 2012

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

require 'iconv'
....
line = Iconv.conv('UTF-8//IGNORE', 'UTF-8', line)
#now variable line has valid utf-8 data

Вы можете попробовать переопределить установщик 'name', чтобы он удалял не-utf8 символы:

def name=(name)
  write_attribute(:name, Iconv.conv('UTF-8//IGNORE', 'UTF-8', name))
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...