提交 71cd0659 编写于 作者: R Ryuta Kamizono

Deserialize a raw value from the database in `changed_in_place?` for `AbstractJson`

Structured type values sometimes caused representation problems (keys
sort order, spaces, etc). A raw value from the database should be
deserialized (normalized) to prevent the problems.
上级 cbf378bc
......@@ -838,11 +838,6 @@ def binary_to_sql(limit) # :nodoc:
end
class MysqlJson < Type::Internal::AbstractJson # :nodoc:
def changed_in_place?(raw_old_value, new_value)
# Normalization is required because MySQL JSON data format includes
# the space between the elements.
super(serialize(deserialize(raw_old_value)), new_value)
end
end
class MysqlString < Type::String # :nodoc:
......
......@@ -6,16 +6,6 @@ class Jsonb < Json # :nodoc:
def type
:jsonb
end
def changed_in_place?(raw_old_value, new_value)
# Postgres does not preserve insignificant whitespaces when
# round-tripping jsonb columns. This causes some false positives for
# the comparison here. Therefore, we need to parse and re-dump the
# raw value here to ensure the insignificant whitespaces are
# consistent with our encoder's output.
raw_old_value = serialize(deserialize(raw_old_value))
super(raw_old_value, new_value)
end
end
end
end
......
......@@ -24,6 +24,10 @@ def serialize(value)
end
end
def changed_in_place?(raw_old_value, new_value)
deserialize(raw_old_value) != new_value
end
def accessor
ActiveRecord::Store::StringKeyedHashAccessor
end
......
......@@ -160,6 +160,17 @@ def test_changes_in_place
assert_not json.changed?
end
def test_changes_in_place_with_ruby_object
time = Time.now.utc
json = JsonDataType.create!(payload: time)
json.reload
assert_not json.changed?
json.payload = time
assert_not json.changed?
end
def test_assigning_string_literal
json = JsonDataType.create!(payload: "foo")
assert_equal "foo", json.payload
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册