Skip to content

Commit

Permalink
Merge pull request rails#49934 from fatkodima/fix-pg-uuid-changed-for…
Browse files Browse the repository at this point in the history
…mats

Fix PostgreSQL `Uuid#change?` to ignore uuid's value formatting
  • Loading branch information
byroot committed Nov 6, 2023
2 parents c0e67e6 + 2c98042 commit 9c85851
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module PostgreSQL
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

Expand All @@ -15,18 +16,27 @@ def type

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
Expand Down
5 changes: 4 additions & 1 deletion activerecord/test/cases/adapters/postgresql/uuid_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,13 @@ def test_invalid_uuid_dont_match_to_nil
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
Expand Down

0 comments on commit 9c85851

Please sign in to comment.