Ассоциация «has_many through» не работает при использовании настраиваемого столбца ActiveRecord :: Type (двоичный) - PullRequest
2 голосов
/ 01 апреля 2019

Я создал следующий тип 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 для двоичного типа?И как заставить его работать так, чтобы он работал?

Ответы [ 2 ]

1 голос
/ 05 апреля 2019

Оказывается, это ошибка в Rails.

Я отправил вопрос об официальном репо , и они работают над ним.

0 голосов
/ 01 апреля 2019

Я не уверен, поможет ли это, но зайдите в config / initializers / type.rb и добавьте

ActiveRecord::Type.register(:token_users, UuidType)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...