在 Rails 中保存后向属性添加了奇怪的字节

Weird Bytes Added to Attribute After Save in Rails

我们遇到了一个疯狂的错误,在保存电子邮件时,大约 90% 的时间看似随机的字节被附加到电子邮件字段。以下是可能发生的情况的示例:

来自参数:'user@example.com'
验证前:'user@example.com'
验证后:'user@example.com'
保存前:'user@example.com'
保存后对象中的值:'user@example.com'
检索刚刚由id创建的记录,并获取id:'user@example.com\u007f'

\u007fUTF-8 delete character!!!)到底从哪里来的?!这是迄今为止出现的最常见的垃圾。下面是一些其他不时出现的有效字节序列的列表:

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

有时我得到的都是垃圾位,由于 PG::CharacterNotInRepertoire 错误,我无法判断是否有比这些更多的字节:

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

考虑到发生的 PG::CharacterNotInRepertoire 错误,我假设这发生在值被保存之前的某处,但超出了我的应用程序代码的范围。

请注意,奇怪的是,用户的任何其他字段都没有发生这种情况。

以下是当前接触电子邮件地址的所有回调:

一些应用信息:

事实证明 pg-ruby < v0.18.0 与 Ruby v2.2 不兼容,尽管没有明显的相反警告...

https://bitbucket.org/ged/ruby-pg/issue/210/crazy-bytes-being-added-to-record

立即升级或获取位。

另请注意,如果您使用的是 Rails 4.2.0,则 pg 0.18.* 存在一个影响写入二进制数据的问题。我目前有 4.2.0 monkey-patched 补丁将在 4.2.1 中。如果您是 运行 4.2.0 和 Ruby 2.2(因此是 pg 0.18.),请参阅 https://github.com/rails/rails/pull/17680 了解详细信息。 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