Solución
Poner esto al final de mi método de API resolvió el problema:
MessageBus.publish("/topic/#{@topic.id}", reload_topic: true, refresh_stream: true)
Esto debería actualizar no solo al usuario actual, sino a cualquier otra persona que esté viendo el tema.
Exploración que me llevó aquí
Sigue leyendo si quieres seguir mi recorrido por la base de código. Lo comparto para cualquiera a quien pueda serle útil.
¿Qué es MessageBus?
Según la explicación de Sam de 2013 sobre MessageBus, parece que el código Ruby puede publicar y suscribirse, mientras que el código Javascript solo puede suscribirse. Ok, entonces, bajo esta arquitectura propuesta, mi código del lado del servidor será responsable de notificar a la interfaz de usuario.
¿Hay algún ejemplo de MessageBus que me sea útil?
Ninguno de los ejemplos de complementos hace nada con MessageBus.
GroupArchivedMessage.move_to_inbox! llama a este código, que está algo cerca de lo que quiero, pero el código de tipo utilizado aquí no me servirá.
MessageBus.publish("/topic/#{topic_id}", { type: "move_to_inbox" }, group_ids: [group_id])
Este código parece prometedor.
MessageBus.publish("/topic/#{@topic.id}", reload_topic: true, refresh_stream: true)
Esta fue la solución final que elegí.
¿Qué sucede cuando el navegador recibe la actualización?
El controlador de temas está suscrito a las actualizaciones del tema que está viendo actualmente. Desencadena “post-stream:refresh”, lo que inicia la actualización. Lo único que encuentro escuchando en el otro extremo es ScrollingPostStream, que vincula un método _refresh al evento. Esto parece ser lo que realmente realiza la actualización.
Por esto, infiero que si quisiera actualizar solo el cliente actual sin enviar la actualización a nadie más, podría llamar al mismo código yo mismo:
this.appEvents.trigger("post-stream:refresh", args)
Y parece que podría llamar a esto desde cualquier componente.
¿Qué pasa con la implementación original de move_posts? ¿Publica en MessageBus?
Investigando el núcleo, veo: El método move_posts() del controlador de temas llama a move_posts_to_destination(), que llama a topic.move_posts(), que llama a new PostMover() y luego a to_topic() o to_new_topic(). Estos métodos no llaman a MessageBus, pero sí llaman a DiscourseEvent.trigger().
Llamo a topic.move_posts() desde mi método de API personalizado. Por lo tanto, mi código llama directamente al modelo y omite toda la lógica existente del controlador:
new_topic = topic.move_posts(current_user, [post.id], {title: title, category_id: category_id})
En mi caso, se llama a move_posts_to() como último paso de la secuencia, que llama a lo siguiente:
DiscourseEvent.trigger(
:posts_moved,
destination_topic_id: destination_topic.id,
original_topic_id: original_topic.id,
)
DiscourseEvent no parece tener nada que ver con MessageBus, sin embargo. ¿Quizás solo se usa para ciclos de vida internos dentro del servidor?
Por lo tanto, concluyo que MessageBus normalmente no se publica para una reubicación de tema.