mirror of https://github.com/rails/rails
Fix PostgreSQL `Uuid#change?` to ignore uuid's value formatting
This commit is contained in:
parent
c0e67e6547
commit
2c98042440
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue