Weird Bytes добавлены в атрибут после сохранения в Rails

Мы испытываем безумную ошибку, где кажущиеся случайные байты составляют около 90% времени, когда они привязаны к полю электронной почты прямо в момент, когда электронное письмо сохраняется. Вот пример того, что может произойти:

From params: '[email protected]'
Before validate: '[email protected]'
After validate: '[email protected]'
Before save: '[email protected]'
Value in object after save: '[email protected]'
Retrieve record just created by id, and fetch id: '[email protected]\u007f'

Где, черт возьми, это \u007f (символ UTF-8 delete!!!)? Это самый распространенный мусор, который появляется. Здесь список некоторых других действительных последовательностей байтов, которые появлялись время от времени:

r\u007f
U\u007f
a\u007f
#m$\u007f

Иногда я получаю полностью мусорные биты, я не могу сказать, есть ли больше байтов из-за ошибки PG::CharacterNotInRepertoire:

0xde 0x4d
0xf6 0x7f
0xbc
0xe3 0x6c 0x24

Учитывая ошибки PG::CharacterNotInRepertoire, которые происходят, я предполагаю, что это происходит где-то непосредственно перед тем, как значение сохраняется, но вне области моего кода приложения.

Обратите внимание, что это странно не происходит для других полей для пользователя.

Вот все обратные вызовы, которые в данный момент касаются адреса электронной почты:

  • #strip! и #downcase! перед проверкой
  • Проверка формата с помощью регулярного выражения \A[A-Za-z0-9._%+-][email protected](?:[A-Za-z0-9-]+\.)+[A-Za-z]{2,20}\z

Некоторые сведения о приложении:

  • Ruby v2.2.0
  • Rails v4.1.8
  • Postgres v9.3.2
  • PG v0.17.1

Ответ 2

Также имейте в виду, что если вы используете Rails 4.2.0, возникает проблема с pg 0.18. *, которая влияет на запись двоичных данных. В настоящее время у меня есть 4.2.0 обезьяна-патч с патчем, который будет в 4.2.1. Подробнее см. https://github.com/rails/rails/pull/17680, если вы используете 4.2.0 с Ruby 2.2 (и, следовательно, с pg 0.18.). Подобные проблемы могут возникать и в Rails 4.0. и 4.1. * - Я не понял, какая версия имеет патч, и выпущены ли эти версии еще.

Моя обезьяна-патч для 4.2.0 выглядит так:

# Should release in Rails 4.2.1
# PostgreSQL, Fix change detection caused by superfluous bytea unescaping
# See https://github.com/rails/rails/pull/17680
if Rails.version == '4.2.0'
  module ActiveRecord
    module ConnectionAdapters
      module PostgreSQL
        module OID # :nodoc:
          class Bytea < Type::Binary # :nodoc:
            def type_cast_from_database(value)
              return if value.nil?
              return value.to_s if value.is_a?(Type::Binary::Data)
              PGconn.unescape_bytea(super)
            end
          end
        end
      end
    end
  end
end