Rails 7 Turbo 框架和多种表单的表单值问题

问题描述 投票:0回答:1

我对 Rails 很陌生。我发现这个奇怪的问题与turbo_frame和多种新形式有关。

我有一个带有

Post
的模型
comments
,当我尝试加载多个表单时,即使我指定使用 Comment.new

,一个表单中的值也会出现在其他表单上
###posts/index.html.erb

<div id="posts">
  <% @posts.each do |post| %>
    <div class="post">
    <%= turbo_frame_tag dom_id(post) do %>
        <%= render 'posts/show', post: post)%>
    <% end %>
    </div>
    <hr>
  <% end %>
</div>


### posts/_show.html.erb
  <% post.comments.each do |comment| %>
    <%= render "comments/comment", post: post, comment: comment %>
  <% end %>
  <%= turbo_frame_tag "comments_#{post.id}" do %>
  <% end %>

  <%= render "comments/add_new_comment", post: post, comment: Comment.new %>
### _add_new_comment.html.erb
<%= turbo_frame_tag "comments_new#{post.id}" do %>
   <%= link_to "Add comment", open_create_new_comment_path(post) %>
<% end %>
### comments/_comment.html.erb
<%= turbo_frame_tag dom_id(comment) do %>
  <div>
    <%= comment.body %>
    <div>
      <%= link_to 'Edit', edit_post_comment_path(comment.post, comment) %>
      <%= link_to 'Delete', post_comment_path(comment.post, comment),
                method: :delete,
                data: { confirm: 'Are you sure?', turbo_method: :delete } %>
    </div>
  </div>
<% end %>
### comments/_form.html.erb
<%= turbo_frame_tag "new_comment_form_#{post.id}" do %>
  <%= form_with(model: [post, Comment.new]) do |form| %>
    <%= form.rich_text_area :body %>
    <%= form.hidden_field :post_id, value: post.id %>
    <%= form.submit "Submit", data: { disable_with: "Submitting..." } %>
  <% end %>
<% end %>

最后是控制器

class CommentsController < ApplicationController
  before_action :set_post
  before_action :set_comment, only: [:edit, :update, :destroy]

  def edit
    render turbo_stream: turbo_stream.replace("comment_#{params[:id]}", partial: "comments/edit_form", locals: {post: @post, comment: @comment})
  end

  def open_create_new
    render turbo_stream: turbo_stream.replace("comments_new#{@post.id}", partial: "comments/form", locals: {post: @post, comment: Comment.new})
  end

  def create
    @comment = Comment.new(comment_params)

    if @comment.save
      respond_to do |format|
        format.turbo_stream do
          render turbo_stream: [
            turbo_stream.prepend("comments_#{@post.id}", partial: "comments/comment", locals: {comment: @comment}),
            turbo_stream.replace("new_comment_form_#{@post.id}", partial: "comments/add_new_comment", locals: {post: @post})
          ]
        end
      end

    else
      respond_to do |format|
        format.turbo_stream { render turbo_stream:turbo_stream.replace("new_comment_form_#{@post.id}", partial: "comments/add_new_comment", locals: {post: @post})}
      end
    end
  end

  # PATCH/PUT /comments/1 or /comments/1.json
  def update
    if @comment.update(comment_params)
      render turbo_stream: turbo_stream.replace("edit_comment_form_#{@comment.id}", partial: "comments/comment", locals: {comment: @comment})
    else
      render turbo_stream: turbo_stream.replace("edit_comment_form_#{@comment.id}", partial: "comments/comment", locals: {comment: @comment})
    end
  end

  # DELETE /comments/1 or /comments/1.json
  def destroy
    @comment.destroy
    respond_to do |format|
      format.turbo_stream do
        render turbo_stream: turbo_stream.remove("comment_#{params[:id]}")
      end
    end
  end

  private

  # Use callbacks to share common setup or constraints between actions.
  def set_comment
    @comment = Comment.find(params[:id])
  end

  def set_post
    @post = Post.friendly.find_by(slug: params[:post_id])
  end

  # Only allow a list of trusted parameters through.
  def comment_params
    params.require(:comment).permit(:body, :post_id, :parent_id)
  end
end

奇怪的是,每个表单都能完美地单独工作,但是如果我从帖子 1 加载表单,输入一些文本,然后打开表单向其他帖子添加评论,则文本与我在表单 1 中输入的文本相同,当我尝试提交表单,日志显示正文为空。

想法?为什么当我将所有内容放入

locals
并使用
Comment.new

时,其中一个的内容会添加到其他内容中
ruby-on-rails hotwire-rails turbo
1个回答
0
投票

这是一个富文本字段的javascript问题,您需要为页面上的每个富文本字段拥有唯一的ID,您可以使用

:namespace
助手的
form_with
选项:

<%= form_with model: [post, Comment.new], namespace: dom_id(post) do |form| %>
  <%= form.rich_text_area :body %>
<% end %>
<input type="hidden" name="comment[body]" id="post_2_comment_body_trix_input_comment" autocomplete="off">
<!--                               namespace: ^^^^^^  -->

删除

turbo_frame_tag
s,你实际上并没有使用它们:

<!-- app/views/posts/index.html.erb -->

<div id="posts">
  <%= render @posts %>
</div>
<!-- app/views/posts/_post.html.erb -->

<div id="<%= dom_id post %>">

  <!-- will append post's comments here -->
  <div id="<%= dom_id post, :comments %>">
    <%= render post.comments %>
  </div>

  <!-- will update with new comment form then back to link -->
  <div id="<%= dom_id post, :new_comment %>">
    <%= link_to "Add comment", new_post_comment_path(post), data: {turbo_stream: true} %>
  </div>

</div>
<!-- app/views/comments/_form.html.erb -->

<%= form_with model: [post, Comment.new], namespace: dom_id(post) do |form| %>
  <%= form.rich_text_area :body %>
  <%= form.submit "Submit", data: {turbo_submits_with: "Submitting..."} %>
<% end %>
<!-- app/views/comments/_comment.html.erb -->

<div id="<%= dom_id comment %>">
  <%= comment.body %>
  <div>
    <%= link_to "Edit", edit_post_comment_path(comment.post, comment), data: {turbo_stream: true} %>
    <%= link_to "Delete", post_comment_path(comment.post, comment), data: {turbo_confirm: "Are you sure?", turbo_method: :delete} %>
  </div>
</div>
# app/controller/comments_controller.rb

def new
  respond_to do |format|
    format.turbo_stream do
      render turbo_stream: turbo_stream.update(
        [@post, :new_comment],
        partial: "comments/form",
        locals: {post: @post, comment: Comment.new}
      )
    end
  end
end

def create
  @comment = @post.comments.new(comment_params)
  if @comment.save
    respond_to do |format|
      format.turbo_stream do
        render turbo_stream: [
          turbo_stream.append(
            [@post, :comments],
            partial: "comments/comment",
            locals: {comment: @comment}
          ),
          turbo_stream.update(
            [@post, :new_comment],
            helpers.link_to("Add comment", new_post_comment_path(@post), data: {turbo_stream: true})
          )
        ]
      end
    end
  else
    respond_to do |format|
      format.turbo_stream do
        render turbo_stream: turbo_stream.update(
          [@post, :new_comments],
          partial: "comments/form",
          locals: {comment: @comment, post: @post}
        )
      end
    end
  end
end

def edit
  respond_to do |format|
    format.turbo_stream do
      render turbo_stream: turbo_stream.update(
        @comment,
        partial: "comments/form",
        locals: {comment: @comment, post: @post}
      )
    end
  end
end

def update
  respond_to do |format|
    if @comment.update(comment_params)
      format.turbo_stream do
        render turbo_stream: turbo_stream.update(@comment)
      end
    else
      format.turbo_stream do
        render turbo_stream: turbo_stream.update(
          @comment,
          partial: "comments/form",
          locals: {comment: @comment, post: @post}
        )
      end
    end
  end
end

def destroy
  @comment.destroy
  respond_to do |format|
    format.turbo_stream { render turbo_stream: turbo_stream.remove(@comment) }
  end
end
© www.soinside.com 2019 - 2024. All rights reserved.