Solution
Placer ceci à la fin de ma méthode d’API a résolu le problème :
MessageBus.publish("/topic/#{@topic.id}", reload_topic: true, refresh_stream: true)
Cela devrait rafraîchir non seulement pour l’utilisateur actuel, mais aussi pour toute autre personne consultant le sujet.
Exploration qui m’a mené ici
Lisez la suite si vous souhaitez suivre mon parcours dans la base de code. Je partage cela pour quiconque cela pourrait être utile.
Qu’est-ce que MessageBus ?
D’après l’explication de Sam en 2013 sur MessageBus, il semble que le code Ruby puisse publier et s’abonner, tandis que le code Javascript ne peut que s’abonner. D’accord, donc sous cette architecture proposée, mon code côté serveur sera responsable de notifier l’interface utilisateur.
Existe-t-il un exemple de MessageBus qui m’est utile ?
Aucun des exemples de plugins ne fait quoi que ce soit avec MessageBus.
GroupArchivedMessage.move_to_inbox! appelle ce code qui est quelque peu proche de ce que je veux, mais le code de type utilisé ici ne fonctionnera pas pour moi.
MessageBus.publish("/topic/#{topic_id}", { type: "move_to_inbox" }, group_ids: [group_id])
Ce code semble prometteur.
MessageBus.publish("/topic/#{@topic.id}", reload_topic: true, refresh_stream: true)
Ce fut la solution finale que j’ai choisie.
Que se passe-t-il lorsque le navigateur reçoit la mise à jour ?
Le contrôleur Topics est abonné aux mises à jour du sujet qu’il visualise actuellement. Il déclenche « post-stream:refresh », ce qui initie le rafraîchissement. La seule chose que je trouve à l’écoute de l’autre côté est ScrollingPostStream qui lie une méthode _refresh à l’événement. Cela semble être ce qui effectue réellement la mise à jour.
Par cela, j’infère que si je voulais simplement mettre à jour le client actuel sans pousser la mise à jour à qui que ce soit d’autre, je pourrais appeler le même code moi-même :
this.appEvents.trigger("post-stream:refresh", args)
Et il semble que je pourrais appeler cela depuis n’importe quel composant.
Qu’en est-il de l’implémentation originale de move_posts ? Publie-t-elle sur MessageBus ?
En enquêtant sur le cœur, je vois : la méthode move_posts() du contrôleur de sujet appelle move_posts_to_destination() qui appelle topic.move_posts() qui appelle new PostMover() puis soit to_topic() soit to_new_topic(). Ces méthodes n’appellent pas MessageBus, mais elles appellent DiscourseEvent.trigger().
J’appelle topic.move_posts() depuis ma méthode d’API personnalisée. Donc mon code appelle directement le modèle, et saute toute la logique existante du contrôleur :
new_topic = topic.move_posts(current_user, [post.id], {title: title, category_id: category_id})
Dans mon cas, move_posts_to() est appelé comme dernière étape de la séquence, qui appelle ce qui suit :
DiscourseEvent.trigger(
:posts_moved,
destination_topic_id: destination_topic.id,
original_topic_id: original_topic.id,
)
DiscourseEvent ne semble rien avoir à voir avec MessageBus, cependant. Peut-être est-il seulement utilisé pour les cycles de vie internes au serveur ?
Je conclus donc que MessageBus n’est normalement pas publié pour un déplacement de sujet.