Переопределение методов include_* в сериализаторах

Привет, @david,

Вопрос по поводу обоснования этого устаревания:

Уведомление об устаревании: add_to_serializer не следует использовать для прямого переопределения методов include_*?

Контекст: DEV: Improve add_to_serializer include_* options (#21220) · discourse/discourse@26b7f8a · GitHub

Я понимаю стремление перевести разработчиков на использование аргумента include_condition при стандартном применении метода add_to_serializer, то есть для добавления собственных методов в сериализаторы.

Однако существуют случаи, когда плагин может захотеть добавить метод include_* в сериализатор, не соответствующий этому сценарию, например, когда вы не определяете, будет ли включён ваш собственный пользовательский атрибут, а переопределяете метод include_* в базовом сериализаторе, например:

Базовый метод: discourse/app/serializers/site_serializer.rb at main · discourse/discourse · GitHub

Я понимаю, что этот конкретный случай можно переосмыслить так, чтобы не требовалось переопределять метод сериализатора site, или такое переопределение можно реализовать другими способами. Однако меня интересует, есть ли inherentный недостаток в разрешении такого использования метода add_to_serializer, и приведёт ли это устаревание к полному отказу от использования метода таким образом.

Да, это было бы моим рекомендацией.

Недавно мы внедрили новую систему для «модификаторов плагинов» — это очень лёгкие точки расширения, похожие на DiscourseEvent, но они принимают входное значение и возвращают результат. В вашем случае вы можете создать PR в ядро, чтобы добавить вызов DiscoursePluginRegistry.apply_modifier в соответствующий метод include_, а затем использовать register_modifier в вашем плагине для переопределения значения.

Скорее всего, мы в итоге полностью заблокируем это, да. К тому же вам действительно не стоит использовать метод, который генерирует предупреждения о депрекации в логах.

Если вам действительно необходимо переопределить метод без поддержки со стороны ядра, то modify_class кажется лучшим выбором. Основная причина, по которой у нас есть отдельный add_to_serializer, заключается в том, что он автоматически определяет метод include_*, чтобы применяться только тогда, когда плагин включён.

Это означает, что фрагмент кода, на который вы ссылаетесь, в настоящее время определяет два метода: include_wizard_required? и include_include_wizard_required? :sweat_smile:

В этом Readme сказано, что он «работает как стек (первым пришёл — первым ушёл)», но это очередь. Стек работает по принципу «первым пришёл — последним ушёл». (Я даже не могу понять, как скопировать текст с телефона).

Хорошо подмечено. Да, стек работает по принципу LIFO, а очередь — по принципу FIFO

Ключевые особенности этих модификаторов:

  • Работают в стеке (первый зарегистрированный вызывается первым)
  • Автоматически отключаются при отключении плагина
  • Передают кумулятивный результат всех вызовов блока вызывающей стороне

Это скорее «стек промежуточного программного обеспечения»: серия методов, выполняемых последовательно, каждый из которых передаёт свой результат на вход следующего метода.

Я не думаю, что попытка применить здесь терминологию LIFO/FIFO сработает: в «стек» ничего не добавляется и не удаляется — здесь нет «выхода».

Ага. То есть не структура данных «стек».

Я уже собирался сказать что-то вроде: «Я получил диплом по информатике в 1987 году и не знаю, чему сейчас учат». :joy:

Это во многом моя проблема. У меня есть недавний почти 10-летний перерыв, когда я почти не подходил к компьютеру (после 25+ лет работы с ними), и это ощущается как огромный пробел в базе знаний.