diff options
-rw-r--r-- | activerecord/CHANGELOG.md | 7 | ||||
-rw-r--r-- | activerecord/lib/active_record/type/serialized.rb | 4 | ||||
-rw-r--r-- | activerecord/test/cases/serialized_attribute_test.rb | 10 |
3 files changed, 20 insertions, 1 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index ce7cc5b11f..7b34cb8ccd 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,10 @@ +* Correctly persist a serialized attribute that has been returned to + its default value by an in-place modification. + + Fixes #19467. + + *Matthew Draper* + * Fix generating the schema file when using PostgreSQL `BigInt[]` data type. Previously the `limit: 8` was not coming through, and this caused it to become `Int[]` data type after rebuilding from the schema. diff --git a/activerecord/lib/active_record/type/serialized.rb b/activerecord/lib/active_record/type/serialized.rb index 732029c723..b22828d371 100644 --- a/activerecord/lib/active_record/type/serialized.rb +++ b/activerecord/lib/active_record/type/serialized.rb @@ -28,7 +28,9 @@ module ActiveRecord def changed_in_place?(raw_old_value, value) return false if value.nil? - subtype.changed_in_place?(raw_old_value, serialize(value)) + raw_new_value = serialize(value) + raw_old_value.nil? != raw_new_value.nil? || + subtype.changed_in_place?(raw_old_value, raw_new_value) end def accessor diff --git a/activerecord/test/cases/serialized_attribute_test.rb b/activerecord/test/cases/serialized_attribute_test.rb index e29f7462c8..7c92453ee3 100644 --- a/activerecord/test/cases/serialized_attribute_test.rb +++ b/activerecord/test/cases/serialized_attribute_test.rb @@ -264,4 +264,14 @@ class SerializedAttributeTest < ActiveRecord::TestCase Topic.serialize(:content, Regexp) end end + + def test_newly_emptied_serialized_hash_is_changed + Topic.serialize(:content, Hash) + topic = Topic.create(content: { "things" => "stuff" }) + topic.content.delete("things") + topic.save! + topic.reload + + assert_equal({}, topic.content) + end end |