问题
It appears that in Rails 3.2.21, saving a serialized hash fails to save a value that comes from one specifc NumberHelper, helper.number_with_delimiter
In a Rails 3.2 app, in model Foo I have:
serialize :stuff, Hash
In the console:
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
It DOES work correctly with helper.number_to_currency()
.
And it works if I set c: String.new(helper.number_with_delimiter(123456))
.
This is a Rails bug, or am I doing something wrong?
回答1:
Yes, this is a Rails (ActiveSupport) bug that was eventually fixed in Rails 4.2.1. From the 4.2.1 release notes:
Fixed a roundtrip problem with AS::SafeBuffer where primitive-like strings will be dumped as primitives
When you use helper.number_with_delimiter
, the resulting object looks and behaves like a String, but in reality it is an ActiveSupport::SafeBuffer
.
helper.number_with_delimiter(123456).class # => ActiveSupport::SafeBuffer < String
When you use:
serialize :stuff, Hash
That means behind the scenes Rails is using YAML format to save the data to the database. There was a bug in SafeBuffer that caused SafeBuffers like "123"
to be mistakenly converted to integers (i.e. 123
) instead of remaining strings when saving and loading to/from YAML.
Again, this is now fixed as of Rails 4.2.1. You can see the fix here:
https://github.com/rails/rails/commit/debe7aedda3665702d1f99a3ffb4a123a6c44e9c
来源:https://stackoverflow.com/questions/29224421/rails-3-2-saving-serialized-hash-will-not-save-number-with-delimiter