You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:使用Turbo Frames和Streams递归渲染评论回复的实时显示问题

问题解决:Turbo Streams/Frames 实时渲染评论回复

核心问题分析

你的代码存在两个关键错误:

  1. 父评论的回复容器仅在已有回复时才渲染,导致新回复创建时Turbo找不到目标DOM元素
  2. Turbo流模板错误地遍历新回复的replies(空集合),而非直接将新回复插入父评论的容器

步骤1:修正评论Partial模板

给每个评论添加固定存在的回复容器,无论当前是否有回复,确保Turbo能定位到目标元素:

<%= turbo_frame_tag comment do %>
  <div>
    <p class="mt-4 text-gray-500 dark:text-gray-400"><%= comment.body %></p>
  </div>
  <%= turbo_frame_tag dom_id(Comment.new) do %>
    <%= render "comments/like_button", comment: comment %>
  <% end %>
  
  <!-- 固定的回复容器:无论有没有回复都保留 -->
  <div class="ml-4">
    <%= turbo_frame_tag nested_dom_id(comment, "replies") do %>
      <% comment.replies.each do |reply| %>
        <%= render 'comments/comment', comment: reply %>
      <% end %>
    <% end %>
  </div>
<% end %>

步骤2:修正Turbo流模板

直接将新创建的回复插入父评论的回复容器,而非遍历空集合:

<%= turbo_stream.update dom_id(Comment.new), "" %>
<% if @comment.parent_id.nil? %>
  <%= turbo_stream.prepend "comments", @comment %>
<% else %>
  <!-- 定位到父评论的回复容器,插入新回复 -->
  <%= turbo_stream.prepend nested_dom_id(@comment.parent, "replies") do %>
    <%= render 'comments/comment', comment: @comment %>
  <% end %>
<% end %>

步骤3:确保控制器与表单正确关联

  1. 控制器create动作需正确设置父评论关联:
def create
  @post = Post.find(params[:post_id])
  @comment = @post.comments.build(comment_params)
  @comment.user = current_user
  # 接收表单传递的parent_id
  @comment.parent_id = params[:comment][:parent_id]

  if @comment.save
    # Turbo自动渲染对应turbo流模板
  else
    # 处理错误逻辑
  end
end
  1. 回复表单需正确传递parent_id:
<%= form_with model: [@post, Comment.new], locals: { parent_comment: comment } do |f| %>
  <%= f.hidden_field :parent_id, value: parent_comment.id %>
  <%= f.text_area :body, placeholder: "写下你的回复..." %>
  <%= f.submit "回复", class: "mt-2 btn" %>
<% end %>

内容的提问来源于stack exchange,提问作者mutebi godfrey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 20:23:09