使用Hotwire Rails向用户的Turbo Stream进行广播

9
我想在Rails中使用Hotwire进行模型更新流式传输。文档中提到创建一个使用模型的流,但我想为每个用户创建一个动态流,以便用户对模型的更改仅流式传输给该用户。
我有一个VideoCall模型,该模型通过连接表与多个用户具有关联关系,因此模型如下所示,并且我已经对其进行了广播。
class VideoCall < ApplicationRecord
  has_and_belongs_to_many :users

  broadcasts_to ->(video_call) {
    video_call.users.map{|u| "video_calls:user_#{u.id}"}
  }, inserts_by: :prepend

  # more code here
end

在 ERB 模板上,我想获取我添加到模型中的更新。
<%= turbo_stream_from "video_calls:user_#{current_user.id}" %>

如果我在 users_video_calls 表中只有一个用户,那么这将是有效的。但是,一旦视频通话中有多个用户,它就不起作用了,我想要广播到所有这些用户的流中。

我的方法正确吗?如何实现动态地向多个用户流广播?

1个回答

14
所以我这样解决了。通过查看源代码,我意识到覆盖三个回调函数在创建、更新和销毁时是有意义的。所以我删除了这段代码。
  broadcasts_to ->(video_call) {
    video_call.users.map{|u| "video_calls:user_#{u.id}"}
  }, inserts_by: :prepend

然后用这个替换了它

  after_create_commit  -> {
    self.users.each do |u|
      broadcast_action_later_to "video_calls:users_#{u.id}", action: :prepend, target: broadcast_target_default
    end
  }

  after_update_commit  -> {
    self.users.each do |u|
      broadcast_replace_later_to "video_calls:users_#{u.id}"
    end
  }

  after_destroy_commit -> {
    self.users.each do |u|
      broadcast_remove_to "video_calls:users_#{u.id}", action: :prepend, target: broadcast_target_default
    end
  }

现在,在上面的代码中,我可以循环遍历每个相关模型,这在我的情况下是每个视频通话有多个用户,并广播给包含用户ID的频道名称。因此,所有订阅视频通话的用户都将收到更新,而不是所有人。


看起来不错。但我认为你的broadcast_remove_to语句中不需要使用action: :prepend - moveson
1
我一直想做同样的事情——使用Hotwire来管理仅限于已登录用户的消息列表。感谢您跟进并提供解决方案。 - dwayne
谢谢,好的解决方案。然而,如果您想更新同一用户的视图(比如说网站在两个不同的浏览器中打开),after_destroy_commit就不起作用了。原因是self.users不包含刚刚删除的用户,无论self是什么(在我的情况下是链接)。我不确定该怎么做。有什么想法吗? - imarg
在调用销毁之前,您可以提取用户。 - Stephane Paquet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接