aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activerecord/CHANGELOG.md7
-rw-r--r--activerecord/lib/active_record/type/serialized.rb4
-rw-r--r--activerecord/test/cases/serialized_attribute_test.rb10
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