Use a custom class for Uuid values

This commit is contained in:
Donal McBreen
2025-11-12 17:16:07 +00:00
committed by Mike Dalessio
parent f4729577b6
commit f6ec9bbeea
2 changed files with 26 additions and 1 deletions
+1 -1
View File
@@ -10,7 +10,7 @@ ActiveSupport.on_load(:active_record) do
end
def quote(value)
if value.is_a?(String) && value.encoding == Encoding::BINARY && value.bytesize == 16
if value.is_a?(ActiveRecord::Type::UuidValue)
# Convert binary UUIDs to hex literals to avoid encoding conflicts in SQL strings
"X'#{value.unpack1('H*')}'"
else
+25
View File
@@ -1,6 +1,30 @@
# Custom UUID attribute type for MySQL binary storage with base36 string representation
module ActiveRecord
module Type
# Wrapper class to distinguish UUID binary values from regular binary strings
class UuidValue
def initialize(binary_string)
@value = binary_string
end
def to_s
@value
end
# Delegate methods needed for SQL quoting
def unpack1(format)
@value.unpack1(format)
end
def bytesize
@value.bytesize
end
def encoding
@value.encoding
end
end
class Uuid < Binary
BASE36_LENGTH = 25 # 36^25 > 2^128
@@ -16,6 +40,7 @@ module ActiveRecord
hex = value.to_s.to_i(36).to_s(16).rjust(32, "0")
binary = hex.scan(/../).map(&:hex).pack("C*")
binary.force_encoding(Encoding::BINARY)
UuidValue.new(binary)
end
def deserialize(value)