我创建了以下 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
(我也写了整个code to replicate the issue)。
为where
生成的SQL has_many
子句类似于以下内容,并且运行良好:
WHERE column = x'4e254953bcdb4793a485ac04131565a7'
为has_many :through
生成的那个不起作用:
WHERE column = '4e254953-bcdb-4793-a485-ac04131565a7'
它不返回任何错误,但不返回任何结果。
问题在于第二个(has_many :through
)不包含x
前缀,也没有删除连字符(如果我手动执行,则可以解决此问题)。 / p>
我能够同时使用 MySQL 和 SQlite 和 Rails 5 和 6 来复制该问题。
为什么has_many :through
关系对于二进制类型不会产生相同的SQL?怎样才能使其正常工作?
答案 0 :(得分:1)
事实证明,这是一个Rails错误。
我已经提交了issue on the official repo,他们正在为此工作。
答案 1 :(得分:0)
我不确定是否有帮助,但是请转到config / initializers / type.rb并添加
ActiveRecord::Type.register(:token_users, UuidType)