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

时间:2015-03-06 02:31:18

标签: ruby-on-rails ruby postgresql utf-8

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

From params: 'user@example.com'
Before validate: 'user@example.com'
After validate: 'user@example.com'
Before save: 'user@example.com'
Value in object after save: 'user@example.com'
Retrieve record just created by id, and fetch 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错误,我假设这是在保存值之前的某个地方发生的,但超出了我的应用程序代码的范围。

请注意,对于用户的任何其他字段都不会发生这种情况。

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

    验证前
  • #strip!#downcase!
  • 使用正则表达式\A[A-Za-z0-9._%+-]+@(?:[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 个答案:

答案 0 :(得分:25)

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

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

立即升级或获取位数。

答案 1 :(得分:2)

另请注意,如果您正在使用Rails 4.2.0,则pg 0.18。*会影响编写二进制数据。我目前有4.2.0猴子修补版本将在4.2.1中修补。有关详细信息,请参阅https://github.com/rails/rails/pull/17680如果您使用Ruby 2.2运行4.2.0(因此使用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