Как настроить алгоритм оценки горячих тем с помощью плагина?

Встроенный алгоритм сортировки «Популярное» очень прост и может не подходить для различных сценариев использования. Исходя из моего базового понимания кодовой базы Discourse, на данный момент отсутствуют настройки сайта, доступные пользователю, или подходящие точки внедрения для плагинов, позволяющие настроить алгоритм сортировки «Популярное». Существует событие topic_hot_scores_updated, но оно вызывается уже после обновления оценок; оно служит для уведомления, но не позволяет переопределить встроенные оценки популярности. Есть две настройки сайта: hot_topics_gravity и hot_topics_recent_days, но у них установлено значение hidden: true, поэтому они не отображаются в административном интерфейсе.

Мы рассматриваем возможность создания плагина для замены встроенного алгоритма оценки популярности. Какой подход будет лучше с точки зрения совместимости и простоты обновления Discourse в будущем? Ниже приведены некоторые из наших идей:

  • Использование monkey-patch для класса TopicHotScore и обновление базы данных в соответствии с нашим собственным алгоритмом.
  • Создание отдельной таблицы для хранения оценок популярности тем и запуск отдельного фоновой задачи для их обновления. Добавление нового маршрута (вместо /hot) для отображения списка тем по нашему собственному алгоритму.
  • Или, возможно, кодовую базу Discourse можно улучшить, чтобы поддержать такой сценарий использования?

Самый простой вариант, но может иметь ограничения в зависимости от ваших целей.

Выполнимо, но сложнее. Изучите как TopicQuery реализует списки

и в частности

  def list_hot
    create_list(:hot, unordered: true, prioritize_pinned: true) do |topics|
      topics = remove_muted(topics, user, options)
      topics.joins("JOIN topic_hot_scores on topics.id = topic_hot_scores.topic_id").order(
        "topic_hot_scores.score DESC",
      )
    end
  end

Добавить ещё один такой метод относительно несложно, хотя нужно учитывать множество движущихся частей. Я реализовал это в своём плагине ‘homepage-filter’, и это может стать хорошей отправной точкой.