Я создал следующий тип ActiveRecord , и хотя has_many
ассоциации работают хорошо, has_many :through
нет:
# app/types/uuid_type.rb
class UuidType < ActiveRecord::Type::Binary
def serialize(value)
super(cast_to_uuid(value)&.raw)
end
def deserialize(value)
cast_to_uuid(super(value)).to_s
end
def cast_value(value)
cast_to_uuid(value).to_s
end
private
def cast_to_uuid(value)
return if value.nil?
case value.size
when 16 then UUIDTools::UUID.parse_raw(value) # From `uuidtools` gem
when 36 then UUIDTools::UUID.parse(value) # From `uuidtools` gem
end
end
end
# app/models/token.rb
class Token < ActiveRecord::Base
attribute :id, UuidType.new, default: SecureRandom.uuid
has_many :token_users
has_many :users, through: :token_users
end
(я такженаписал полный код для репликации проблемы ).
Предложение SQL where
, сгенерированное для has_many
, похоже на следующее и прекрасно работает:
WHERE column = x'4e254953bcdb4793a485ac04131565a7'
Хотя сгенерированный для has_many :through
не работает:
WHERE column = '4e254953-bcdb-4793-a485-ac04131565a7'
Не возвращает ошибок, но не возвращает результатов .
Проблема в том, что второй (has_many :through
) не включает префикс x
и также не удаляет дефисы (если я это сделаю вручную, это решит проблему).
Мне удалось воспроизвести проблему с обоими MySQL и SQlite и обоими Rails 5 и 6 .
Почему отношение has_many :through
не производит тот же SQL для двоичного типа?И как заставить его работать так, чтобы он работал?