ruby-on-rails 如何使用turbo帧和流递归渲染部分

rryofs0p  于 2023-11-20  发布在  Ruby
关注(0)|答案(2)|浏览(124)
  • 你好,我对涡轮流和帧相对较新,我目前面临着使用涡轮帧和流渲染回复评论的问题。

让我来解释一下我的设置。我有一个Comment模型,我利用同一个表来包含评论和它们各自的回复。

  • 下面是comment.rb
class Comment < ApplicationRecord
      belongs_to :post
      belongs_to :user
      has_many :likes, as: :likeable
      scope :ordered, -> { order(id: :desc) }
      belongs_to  :parent, class_name: 'Comment', optional: true
      has_many    :replies, class_name: 'Comment', foreign_key: :parent_id, dependent: :destroy
    
      validates :body, presence: true
    end

字符串

  • 下面是我的帖子显示页面,在那里我想渲染评论所有的评论
<%= turbo_frame_tag "comments" do%>
      <%= render @comments, post: @post, comment: @comment %>
    <% end %>

  • 下面是我的评论部分,我希望每个父评论都有递归嵌套的回复
<%= turbo_frame_tag comment do%>
  <div class="">
      <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 %>
    <% if comment.replies.any? %>
      <% comment.replies.each do |reply| %>
        <div class="ml-4">
          <%= turbo_frame_tag nested_dom_id(comment, "replies") do%>
            <%= render 'comments/comment', comment: reply %>
          <% end %>
        </div>
      <% end %>
    <% end %>
  </div>
<% end %>


app/views/comments/create_turbo.stream.erb

<%= turbo_stream.update Comment.new, "" %>
<% if @comment.parent_id.nil? %>
  <%= turbo_stream.prepend "comments", @comment%>
<% else %>
  <% @comment.replies.each do |reply| %>
    <%= turbo_stream.prepend nested_dom_id(@comment, "replies") do%>
      <%= render 'comments/comment', comment: reply %>
    <% end %>
  <% end %>
<% end %>

  • 问题是,只有在我手动刷新页面后,子评论才会显示良好的嵌套,这不是我想要的情况。我想要的是,当我创建回复时,我希望它在父评论下呈现,而不刷新页面。
  • 任何帮助将不胜感激
i7uaboj4

i7uaboj41#

就像这样:

# app/views/comments/index.html.erb

<%= link_to "New comment", new_comment_path, data: {turbo_frame: :new_comment} %>

<%= turbo_frame_tag :new_comment, class: "contents" %>

<%= tag.div id: :comments do %>
  <%= render @comments.where(parent_id: nil) %>
<% end %>
# app/views/comments/_comment.html.erb

<%= tag.div id: dom_id(comment) do %>
  <%= comment.body %>

  <%= link_to "Reply", new_comment_path(parent_id: comment),
    data: {turbo_frame: dom_id(comment, :new_comment)} %>

  <%= tag.div id: dom_id(comment, :comments), class: "pl-4" do %>
    <%= render comment.replies %>
  <% end %>

  <%= turbo_frame_tag comment, :new_comment, class: "contents" %>
<% end %>
# app/views/comments/new.html.erb

# grab parent_id from url params
<% @comment.parent_id ||= params[:parent_id] %>

<%= turbo_frame_tag *[@comment.parent, :new_comment].compact, class: "contents" do %>
  <%= render "form", comment: @comment %>
<% end %>
# app/views/comments/_form.html.erb

<%= form_with model: comment, class: "contents" do |f| %>
  <%= f.hidden_field :parent_id %>
  <%= f.text_area :body, placeholder: :comment %>

  <%= f.submit class: "btn-primary" %>
<% end %>
# app/controllers/comments_controller.rb

def create
  @comment = Comment.new(comment_params)

  respond_to do |format|
    if @comment.save
      format.turbo_stream do
        if @comment.parent
          render turbo_stream: [
            # remove reply form
            turbo_stream.update(helpers.dom_id(@comment.parent, :new_comment)),
            # add new reply under the corresponding parent comment
            turbo_stream.append(helpers.dom_id(@comment.parent, :comments), @comment),
          ]
        else
          render turbo_stream: [
            turbo_stream.update(:new_comment),
            turbo_stream.append(:comments, @comment),
          ]
        end
      end
      format.html { redirect_to comments_url, notice: "Created." }
    else
      format.html { render :new, status: :unprocessable_entity }
    end
  end
end

注意,turbo-railsv1.5.0更新了turbo_frame_tag以生成与dom_id相同的id:

v1.5.0之前,你可以这样做:

<%= turbo_frame_tag :new_comment, comment, class: "contents" %>

<%= turbo_frame_tag *[:new_comment, @comment.parent].compact, class: "contents" do %>
  #...


测试结果:
x1c 0d1x的数据

<div>
  <a data-turbo-frame="new_comment" href="/comments/new">New comment</a>
  <turbo-frame class="contents" id="new_comment"></turbo-frame>

  <div id="comments">
    <div id="comment_39">
      first comment
      <a data-turbo-frame="new_comment_comment_39" href="/comments/new?parent_id=39">Reply</a>
      <div id="comments_comment_39" class="pl-4">
        <div id="comment_41">
          first reply
          <a data-turbo-frame="new_comment_comment_41" href="/comments/new?parent_id=41">Reply</a>
          <div id="comments_comment_41" class="pl-4"></div>
          <turbo-frame class="contents" id="new_comment_comment_41"></turbo-frame>
        </div>
        <div id="comment_42">
          second reply
          <a data-turbo-frame="new_comment_comment_42" href="/comments/new?parent_id=42">Reply</a>
          <div id="comments_comment_42" class="pl-4">
            <div id="comment_43">
              first reply to second reply
              <a data-turbo-frame="new_comment_comment_43" href="/comments/new?parent_id=43">Reply</a>
              <div id="comments_comment_43" class="pl-4"></div>
              <turbo-frame class="contents" id="new_comment_comment_43"></turbo-frame>
            </div>
          </div>
          <turbo-frame class="contents" id="new_comment_comment_42"></turbo-frame>
        </div>
      </div>
      <turbo-frame class="contents" id="new_comment_comment_39"></turbo-frame>
    </div>
    <div id="comment_40">
      second comment
      <a data-turbo-frame="new_comment_comment_40" href="/comments/new?parent_id=40">Reply</a>
      <div id="comments_comment_40" class="pl-4"></div>
      <turbo-frame class="contents" id="new_comment_comment_40"></turbo-frame>
    </div>
  </div>
</div>

qmb5sa22

qmb5sa222#

- I made few changes to make it work

<% if @comment.parent_id.nil? %>
<%= turbo_stream.prepend "comments" do %>
<%= render @comment %>
<% end %>
<% else %>
<%= turbo_stream.after dom_id(@comment.parent) do %>

<%= render @comment %>

<% end %>
<% end %>

 - now i can have comments rendered recursively

字符串

相关问题