Модификация сериализатора категории ведет себя иначе в версии 2.4.0

После обновления до версии Release v2.4.0.beta2 · discourse/discourse · GitHub почти все наши плагины (например, предпросмотр списков тем, события, локации, рейтинги и т. д.) столкнулись с проблемой в методе add_to_serializer файла plugin.rb.

Существующее использование следовало этому формату:

add_to_serializer(:serializer, property) { value }

Это больше не работает в производственной среде. В среде разработки оно по-прежнему функционирует.

Сначала я подумал, что это может быть связано с тем, как обрабатывается включение плагинов. Поскольку метод _include? у add_to_serializer использует состояние enabled?:

if define_include_method
   # Не включать сериализованные методы, если плагин отключен
  klass.public_send(:define_method, "include_#{attr}?") { plugin.enabled? }
end

Однако использование системы enabled_site_setting не кажется решением проблемы. Более того, enabled? по-прежнему, похоже, по умолчанию возвращает true:

def enabled?
  @enabled_site_setting ? SiteSetting.get(@enabled_site_setting) : true
end

Чтобы решить эту срочную проблему, мы изменили способ сериализации данных нашими плагинами, но, если возможно, я хотел бы разобраться в корне проблемы. Есть ли у кого-нибудь идеи, что здесь происходит?

cc @merefield, @fzngagan

Это крайне необычно, поскольку мы используем это в опросах, и они точно не сломаны. Единственное, что я могу предположить, — они были сломаны в бета-версии, но исправлены в мастер-ветке? Можете ли вы проверить на ветке tests-passed и посмотреть, работают ли они?

Я проверю это подробнее сегодня. Использование в опросах немного отличается, так как метод _include? всегда вызывается с третьим параметром false. Я подозреваю, что проблема может быть в методе include?.

add_to_serializer(:post, :polls_votes, false)

Похоже, что эта проблема специфична для изменений в сериализаторах категорий.

На https://staging.discourse.angusmcleod.com.au установлен только один плагин — “test-add-to-serializer”.

Как видно из файла plugin.rb, внесено несколько изменений в сериализаторы.

Изменения в сериализаторах, не относящихся к категориям, работают корректно, но изменения в сериализаторе basic_category работают только в режиме разработки.

Свойства тестовой категории отсутствуют по адресу:

https://staging.discourse.angusmcleod.com.au/categories.json

или

https://staging.discourse.angusmcleod.com.au/c/records-musicians.json

Однако другие тестовые свойства присутствуют по адресу:

https://staging.discourse.angusmcleod.com.au/t/this-is-a-title-of-a-topic/42.json

или

https://staging.discourse.angusmcleod.com.au/latest.json

Таким образом, проблема, по-видимому, связана не с методом add_to_serializer как таковым, а именно с изменением сериализатора basic_category.

@j.jaffeux @dan Привет :), похоже, вы недавно поработали над discourse-voting, чтобы решить ту же проблему, которую я описал выше.

Не знаете, почему больше недостаточно добавлять свойства в basic_category_serializer?

Я могу подтвердить, что это влияет на тесты-passed

Дэн отсутствует, но по сути у нас есть три разных места, где мы сериализуем категории с разным объемом данных. Посмотрим, есть ли способ убрать миксин, который усложняет понимание этого кода.

Исправлено и перенесено в стабильную и бета-версии.

Дэн правильно настроил структуру наследования, проблема заключалась лишь в том, что у нас был очень-очень-очень давно существующий баг в ядре.

Спасибо, @sam, очень ценно.

Спасибо за сообщение и настойчивость в этом вопросе — было очень непросто найти корень проблемы. Я потратил некоторое время на изучение внутреннего устройства Rails, чтобы разобраться в этом.

Обязательно ознакомьтесь с новым тестом, если вам интересно, как мы гарантируем, что эта проблема не возникнет в будущем.

Огромное спасибо, @sam, за быстрое исправление.

@angus, будет ли работать наш плагин без недавних изменений, которые мы внесли из-за этого исправления?