Rails 3.2、保存序列化hash不会保存number_with_delimiter()

Rails 3.2, saving serialized hash will not save number_with_delimiter()

似乎在 Rails 3.2.21 中,保存序列化哈希无法保存来自一个特定 NumberHelper 的值,helper.number_with_delimiter

在 Rails 3.2 应用程序中,在 Foo 模型中我有:

serialize :stuff, Hash

在控制台中:

f = Foo.create
f.stuff = { a: "aaaa", b: 1111, c: helper.number_with_delimiter(123456) }
=> {:a=>"aaaa", :b=>1111, :c=>"123,456"} # so far so good
f.save!
f.stuff
=> {:a=>"aaaa", :b=>1111, :c=>123456} # c should be a STRING

它确实可以与 helper.number_to_currency() 一起正常工作。

如果我设置 c: String.new(helper.number_with_delimiter(123456)) 就可以了。

这是一个 Rails 错误,还是我做错了什么?

是的,这是一个 Rails (ActiveSupport) 错误,最终在 Rails 4.2.1 中修复。来自 4.2.1 发行说明:

Fixed a roundtrip problem with AS::SafeBuffer where primitive-like strings will be dumped as primitives

当您使用 helper.number_with_delimiter 时,生成的对象看起来和行为都像一个字符串,但实际上它是一个 ActiveSupport::SafeBuffer

helper.number_with_delimiter(123456).class # => ActiveSupport::SafeBuffer < String

当您使用时:

serialize :stuff, Hash

这意味着在幕后Rails正在使用YAML格式将数据保存到数据库中。 SafeBuffer 中存在一个错误,导致像 "123" 这样的 SafeBuffers 在保存和加载 to/from YAML 时被错误地转换为整数(即​​ 123)而不是剩余的字符串。

同样,此问题现已从 Rails 4.2.1 开始修复。您可以在此处查看修复:

https://github.com/rails/rails/commit/debe7aedda3665702d1f99a3ffb4a123a6c44e9c