【问题标题】:How to fix extra data appearing in the ERB generated HTML如何修复出现在 ERB 生成的 HTML 中的额外数据
【发布时间】:2020-02-03 14:21:59
【问题描述】:

我正在按照ruby-on-rails 指令指南创建一个简单的blog Web 应用程序:https://guides.rubyonrails.org/getting_started.html#generating-a-controller

我所有的项目文件都与指南中的几乎相同。

app/views/articles/show.html.erb

<p>
  <strong>Title:</strong>
  <%= @article.title %>
</p>

<p>
  <strong>Text:</strong>
  <%= @article.text %>
</p>

<h2>Add a comment:</h2>
<%= render 'comments/form' %>

<h2>Comments (<%= @article.comments.count %>)</h2>
<%= render 'comment_section' %>
<%#= render @article.comments %>

<%= link_to 'Edit', edit_article_path(@article) %> |
<%= link_to 'Delete', article_path(@article),
            method: :delete,
            data: {confirm: 'Are you sure?'} %> |
<%= link_to 'Back', articles_path %>

app/views/comments/_form.html.erb

<%= form_with(model: [@article, @article.comments.build], local: true) do |form| %>
  <p>
    <%= form.label :commenter %><br>
    <%= form.text_field :commenter %>
  </p>
  <p>
    <%= form.label :body %><br>
    <%= form.text_area :body %>
  </p>
  <p>
    <%= form.submit %>
  </p>
<% end %>

app/views/articles/_comment_section.html.erb

<% if @article.comments.count > 0 %>
  <%= render @article.comments %>
<% else %>
  <p>There are no comments yet!</p>
<% end %>

app/views/comments/_comment.html.erb

<p>
  <strong>Commenter:</strong>
  <%= comment.commenter %>
</p>

<p>
  <strong>Comment:</strong>
  <%= comment.body %>
</p>

<p>
  <%= link_to 'Delete comment', [comment.article, comment],
              method: :delete,
              data: {confirm: 'Are you sure you want to delete this comment?'}
  %>

没有 cmets 的简单文章按预期工作:

但是,当显示包含一些实际 cmets 的文章时,最后会显示一个额外的空评论:

当我尝试删除该评论时,我收到以下错误(路径中的 11 是 article_id):

删除其他 cmets 可以正常工作。

我认为可能相关的其余文件:

app/config/routes.rb

Rails.application.routes.draw do
  get 'welcome/index'

  resources :articles do
    resources :comments
  end

  root 'welcome#index'
end

app/models/article.rb

class Article < ApplicationRecord
  has_many :comments, dependent: :destroy
  validates :title, presence: true, length: {minimum: 5}
end

app/models/comment.rb

class Comment < ApplicationRecord
  belongs_to :article
end

app/controllers/articles_controller.rb

class ArticlesController < ApplicationController
  def index
    @articles = Article.all
  end

  def show
    @article = Article.find(params[:id])
  end

  def new
    @article = Article.new
  end

  def edit
    @article = Article.find(params[:id])
  end

  def create
    @article = Article.new(article_params)
    if @article.save
      redirect_to @article
    else
      render 'new'
    end
  end

  def update
    @article = Article.find(params[:id])

    if @article.update(article_params)
      redirect_to @article
    else
      render 'edit'
    end
  end

  def destroy
    @article = Article.find(params[:id])
    @article.destroy

    redirect_to articles_path
  end

  private

  def article_params
    params.require(:article).permit(:title, :text)
  end
end

app/controllers/comments_controller.rb

class CommentsController < ApplicationController
  def create
    @article = Article.find(params[:article_id])
    @comment = @article.comments.create(comment_params)
    redirect_to article_path(@article)
  end

  def destroy
    @article = Article.find(params[:article_id])
    @comment = @article.comments.find(params[:id])
    @comment.destroy
    redirect_to article_path(@article)
  end

  private
  def comment_params
    params.require(:comment).permit(:commenter, :body)
  end
end

我正在使用:

ruby 2.6.5p114

Rails 6.0.0

sqlite3 3.8.7.2

RubyMine 2019.2.3

我正在 Windows 上开发

【问题讨论】:

    标签: html ruby-on-rails ruby erb


    【解决方案1】:

    发生这种情况的原因是这一行:

    &lt;%= form_with(model: [@article, @article.comments.build], local: true) do |form| %&gt;

    写着@article.comments.build 的部分是在文章上建立一个空评论。如果文章中没有 cmets,而您要打印出@article.comments.count,那么它将为零。这样做是因为@article.comments.count 运行查询,并且由于尚未保存空白评论,因此它不会将其计入 cmets 计数。

    附带说明,@article.comments.size 将返回 1,因为在这种情况下,它返回与空白注释的关系的大小。这就是为什么当文章没有 cmets 时您不会得到空白评论的原因。

    但是,如果您已经有评论并打印出@article.comments.count,它将为 1,因为现在您在数据库中保存了评论。现在,这会将您的 cmets 呈现在页面上。问题是@article.comments 返回值中有一个空白注释。这会打印到屏幕上,并且由于它没有 id,因此删除的路线会像 /article/11/comments 这样呈现,没有注释 id。这条路线不存在,所以会报错。

    解决此问题的一种可能方法是更改​​ comment_section 部分中的这一行:

    &lt;%= render @article.comments %&gt;

    到这里:

    &lt;%= render @article.comments.select { |comment| comment.persisted? %&gt;

    更新:

    我认为 arieljuod 的解决方案更干净,改变这一点:

    &lt;%= form_with(model: [@article, @article.comments.build], local: true) do |form| %&gt;

    到这里:

    &lt;%= form_with(model: [@article, Comment.new], local: true) do |form| %&gt;

    【讨论】:

    • 与其跳过非持久化的评论,也许将@article.comments.build 改为Comment.new 就足够了,而且更干净。
    • @arieljuod,我同意,这会更干净一些,我可能会自己做:D
    【解决方案2】:

    在你的views/comments/_comment.html.erb

    改变

      <%= link_to 'Delete comment', [comment.article, comment],
              method: :delete,
              data: {confirm: 'Are you sure you want to delete this comment?'} %>
    

      <%= link_to 'Delete comment', comment_path(comment),
              method: :delete,
              data: {confirm: 'Are you sure you want to delete this comment?'} %>
    

    【讨论】:

    • 我尝试了您的建议,但稍作改动。而不是comment_path,我使用article_comment_path。还是不行
    猜你喜欢
    • 1970-01-01
    • 2020-12-07
    • 1970-01-01
    • 1970-01-01
    • 2017-10-22
    • 1970-01-01
    • 1970-01-01
    • 2016-10-28
    • 1970-01-01
    相关资源
    最近更新 更多