Полиморфная ассоциация Rails 5 с перечислением выдает «ОШИБКА: недопустимый синтаксис ввода для типа integer».

#ruby-on-rails #ruby #ruby-on-rails-5

Вопрос:

У меня есть Log модель, которая принадлежит многим моделям через полиморфную ассоциацию. Для столбца типа он использует enum , который отлично работал с Rails 4.2 , но после обновления до Rails 5 он выбрасывает ERROR: invalid input syntax for type integer

 class Log
  enum loggable_type: %i[a b c d]
  # ...
end
 
 class A
  has_many :logs, as: :loggable, dependent: :destroy
  # ...
end
 

При извлечении журналов:

 a = A.find id
a.logs
 

Это приводит к следующей ошибке:

 ActiveRecord::StatementInvalid (PG::InvalidTextRepresentation: ERROR:  invalid input syntax for type integer: "A")
: SELECT "logs".* FROM "logs" WHERE "logs"."loggable_id" = $1 AND "logs"."loggable_type" = $2
 

С Rails 4.2 тот же код работал нормально. Вот тот же вопрос:

 > a.logs
  Log Load (2.0ms)  SELECT "logs".* FROM "logs" WHERE "logs"."loggable_id" = $1 AND "logs"."loggable_type" = $2  [["loggable_id", 1111111], ["loggable_type", 0]]
 => #<ActiveRecord::Associations::CollectionProxy []>
 

Что мне нужно сделать, чтобы это работало для Rails 5?

Комментарии:

1. Возможно, вы можете попытаться явно определить перечисление enum loggable_type: {a: 'A', b: 'B', c: 'C'} , потому что прямо сейчас, если вы сделаете Logs.loggable_types, вы получите {a: 0, b: 1, c: 2}

2. перенести loggable_type тип столбца в строку

3. Спасибо, ребята, что попытались помочь. Я нашел решение и опубликовал то же самое.

4. @Int’Lmanofcodingmystery позвольте мне попробовать ваше решение и посмотреть, работает ли оно, но я уже исправил проблему с помощью polymorphic_integer_type gem.

Ответ №1:

Согласно документам Rails и поднятой здесь проблеме, столбец полиморфного типа должен быть строкой, а не целым числом. При таком подходе мне пришлось перенести старые данные.

К счастью, существует тип gem polymorphic_integer_type, который существует для решения точно такой же проблемы.

После включения драгоценного камня в Gemfile и запуска пакета все, что мне нужно было сделать, это:

 class Log
  include PolymorphicIntegerType::Extensions
  belongs_to :loggable, polymorphic: { 1 => 'A', 2 => 'B', 3 => 'C', 4 => 'D' }
end
 

И это сработало как заклинание.