Fix PostgreSQL `Uuid#change?` to ignore uuid's value formatting

This commit is contained in:
fatkodima 2023-11-05 23:42:53 +02:00
parent c0e67e6547
commit 2c98042440
2 changed files with 18 additions and 5 deletions

View File

@ -6,6 +6,7 @@ module ActiveRecord
module OID # :nodoc:
class Uuid < Type::Value # :nodoc:
ACCEPTABLE_UUID = %r{\A(\{)?([a-fA-F0-9]{4}-?){8}(?(1)\}|)\z}
CANONICAL_UUID = %r{\A[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}\z}
alias :serialize :deserialize
@ -15,18 +16,27 @@ module ActiveRecord
def changed?(old_value, new_value, _new_value_before_type_cast)
old_value.class != new_value.class ||
new_value && old_value.casecmp(new_value) != 0
new_value != old_value
end
def changed_in_place?(raw_old_value, new_value)
raw_old_value.class != new_value.class ||
new_value && raw_old_value.casecmp(new_value) != 0
new_value != raw_old_value
end
private
def cast_value(value)
casted = value.to_s
casted if casted.match?(ACCEPTABLE_UUID)
value = value.to_s
format_uuid(value) if value.match?(ACCEPTABLE_UUID)
end
def format_uuid(uuid)
if uuid.match?(CANONICAL_UUID)
uuid
else
uuid = uuid.delete("{}-").downcase
"#{uuid[..7]}-#{uuid[8..11]}-#{uuid[12..15]}-#{uuid[16..19]}-#{uuid[20..]}"
end
end
end
end

View File

@ -121,10 +121,13 @@ class PostgresqlUUIDTest < ActiveRecord::PostgreSQLTestCase
assert_empty UUIDType.where(guid: "foobar")
end
def test_uuid_change_case_does_not_mark_dirty
def test_uuid_change_format_does_not_mark_dirty
model = UUIDType.create!(guid: "abcd-0123-4567-89ef-dead-beef-0101-1010")
model.guid = model.guid.swapcase
assert_not_predicate model, :changed?
model.guid = "{#{model.guid}}"
assert_not_predicate model, :changed?
end
class DuckUUID