我正在尝试从
broadcasts_to
模型设置涡轮流 Comment
。开发模式下,服务器是Puma,ActionCable使用的是redis
。
在创建和更新时,它会将更新的广播作业排入队列,但不运行该作业。我在日志中没有发现任何错误。
class Comment < AbstractModel
belongs_to :target, polymorphic: true
belongs_to :user
after_create :notify_users
broadcasts_to(->(comment) { [comment.target, :comments] },
inserts_by: :prepend, partial: "comments/comment",
target: "comments")
Started PATCH "/comments/195474" for ::1 at 2024-05-10 19:03:52 -0700
Processing by CommentsController#update as TURBO_STREAM
[ActiveJob] Enqueued Turbo::Streams::ActionBroadcastJob (Job ID: 06e29c2c-ae3f-4b8f-b3f9-92486733bb63) to SolidQueue(default) with arguments: "Z2lkOi8vbXVzaHJvb20tb2JzZXJ2ZXIvT2JzZXJ2YXRpb24vNTE1NzEz:comments", {:action=>:replace, :target=>#<GlobalID:0x0000000137a4fe38 @uri=#<URI::GID gid://my-site/Comment/195474>>, :targets=>nil, :attributes=>{}, :partial=>"comments/comment", :locals=>{:comment=>#<GlobalID:0x0000000137a4f5f0 @uri=#<URI::GID gid://mushroom-observer/Comment/195474>>, :request_id=>"7d235d60-d154-43d1-9910-21d343e174e8"}}
接下来发生的事情不是运行作业,而是为当前用户重新渲染整个视图(posts_controller#show),而不仅仅是部分视图。
Started GET "/posts/515713" for ::1 at 2024-05-10 20:06:31 -0700
Processing by PostsController#show as TURBO_STREAM
这会为编辑该帖子的用户重新呈现带有更新评论的帖子,但不会将更新评论广播给隐身窗口中的其他用户。两个用户都订阅了同一频道,并显示具有相同签名频道的
<turbo-cable-stream-source connected>
元素。
我该如何调试这个?
销毁时,Rails 按预期同步广播
remove
,即不是作为作业,并且它立即执行:
Started DELETE "/comments/195468" for ::1 at 2024-05-10 19:09:25 -0700
Processing by CommentsController#destroy as TURBO_STREAM
[ActionCable] Broadcasting to Z2lkOi8vbXVzaHJvb20tb2JzZXJ2ZXIvT2JzZXJ2YXRpb24vNTE1NzEz:comments: "<turbo-stream action=\"remove\" target=\"comment_195468\"></turbo-stream>"
Turbo::StreamsChannel transmitting "<turbo-stream action=\"remove\" target=\"comment_195468\"></turbo-stream>" (via streamed from Z2lkOi8vbXVzaHJvb20tb2JzZXJ2ZXIvT2JzZXJ2YXRpb24vNTE1NzEz:comments)
Turbo::StreamsChannel transmitting "<turbo-stream action=\"remove\" target=\"comment_195468\"></turbo-stream>" (via streamed from Z2lkOi8vbXVzaHJvb20tb2JzZXJ2ZXIvT2JzZXJ2YXRpb24vNTE1NzEz:comments)
Turbo::StreamsChannel transmitting "<turbo-stream action=\"remove\" target=\"comment_195468\"></turbo-stream>" (via streamed from Z2lkOi8vbXVzaHJvb20tb2JzZXJ2ZXIvT2JzZXJ2YXRpb24vNTE1NzEz:comments)
这会同时删除两个用户的评论。 (但是为什么日志中有 3 行?)
我的评论控制器没有给出
format.turbo_stream
的回复。我的理解是,对于 broadcasts_to
和 partial
,我 不应该 在控制器中提供 turbo_stream
响应,Rails 会解决这个问题。
# comments_controller.rb
def update
# ...update the comment if validated, then:
respond_to do |format|
# format.turbo_stream do
# render(
# turbo_stream: turbo_stream.prepend(
# :comments, partial: "comments/comment", locals: { comment: @comment }
# )
# )
# end
format.html do
redirect_to(@target)
end
end
end
我相信,视图是从正确的流中流出的。显示对象的所有注释的部分是
comments/comments_for_object
。该部分包含 #comments
div,并为该 div 内的每个评论调用 comments/comment
部分:
# app/views/comments/comments_for_object.erb
<%= turbo_stream_from(target, :comments) %>
<%=
tag.div(
class: "panel panel-default", id: "comments_for_object"
) do
concat([
tag.div(class: "panel-heading") do
tag.h4(class: "panel-title") do
concat(:COMMENTS.t)
concat(tag.span(new_comment_link(object, btn_class: nil, icon: true),
class: "float-right")) if controls
end
end,
# this is the element that should receive the turbo-stream
# is this the right id for the div, or should it match the
# channel name?
tag.div(id: "comments",
class: "list-group list-group-flush comments",
data: { controller: "section-update",
updated_by: "modal_comment" }) do
# we want to show a message if no comments yet
if comments.empty?
tag.div(:show_comments_no_comments_yet.t, class: "list-group-item")
else
comments.each do |comment|
# the individual comment
concat(render(partial: "comments/comment", object: comment))
end
end
end
].safe_join)
concat(
tag.div(class: "panel-footer") do
link_to(:show_comments_and_more.t(num: and_more),
comments_path(target: object.id, type: object.class.name),
class: "float-right")
end
) if controls && limit && and_more > 0
end %>
# app/views/comments/comment.erb
<%# do i need this? %>
<%# turbo_stream_from(target, :comment) %>
<%= tag.div(class: "list-group-item comment", id: dom_id(comment)) do
...
end %>
我需要为部分中的
turbo_stream_from
和模板中的:comment
分别声明:comments
吗?
这是一个成熟的 Rails 7.1.3/Ruby 3.3.0 应用程序,其中 Turbo、Stimulus、importmaps、ActiveJob 和 SolidQueue 已经运行正常。我正在开发中运行 puma 服务器,并且 redis 正在运行。 Websocket 连接似乎一切正常。
# cable.yml
development:
adapter: redis
url: redis://localhost:6379/1
我错过了什么?
哦哇。我忘记启动 Solid Queue。这就是作业没有运行的原因。
🫣