Как исправить дополнительные данные, появляющиеся в HTML, сгенерированном ERB - PullRequest
0 голосов
/ 05 октября 2019

Я следую ruby-on-rails инструкции по созданию простого blog веб-приложения: 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?'}
  %>

Простая статья без комментариев работает, как и ожидалось:

Empty comment section

Однако при показе статьи сДля некоторых реальных комментариев в конце отображается дополнительный пустой комментарий:

Single comment

Когда я пытаюсь удалить этот комментарий, я получаю следующую ошибку (11 впуть - это article_id):

Deletion error

Удаление других комментариев работает нормально.

Остальные файлы, которые я считаю актуальными:

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

Ответы [ 2 ]

1 голос
/ 05 октября 2019

Причина, по которой это происходит, заключается в следующей строке:

<%= form_with(model: [@article, @article.comments.build], local: true) do |form| %>

Часть, в которой написано @article.comments.build, создает пустой комментарий к статье. Если к статье нет комментариев, и вы должны были распечатать @article.comments.count, это будет ноль. Это происходит потому, что @article.comments.count выполняет запрос, и поскольку пустой комментарий еще не сохранен, он не учитывается при подсчете комментариев.

В качестве примечания, @article.comments.size вернет 1, так как в этом случае он возвращает размер отношения с пустым комментарием. Вот почему вы не получите пустой комментарий, когда в статье нет комментариев.

Однако, если бы у вас уже был комментарий и распечатали @article.comments.count, это был бы 1, потому что теперь у вас есть сохраненныйкомментарий в базе данных. Это делает ваши комментарии на странице сейчас. Дело в том, что внутри возвращаемого значения @article.comments есть пустой комментарий. Это выводится на экран, и так как у него нет идентификатора, маршрут для удаления отображается как /article/11/comments без идентификатора комментария. Этот маршрут не существует, поэтому вы получаете сообщение об ошибке.

Один из возможных способов исправить это - изменить эту строку в вашем comment_section частичном из этого:

<%= render @article.comments %>

на это:

<%= render @article.comments.select { |comment| comment.persisted? %>

ОБНОВЛЕНИЕ:

Я думаю, что решение arieljuod еще чище, чтобы изменить это:

<%= form_with(model: [@article, @article.comments.build], local: true) do |form| %>

К этому:

<%= form_with(model: [@article, Comment.new], local: true) do |form| %>

0 голосов
/ 05 октября 2019

в вашем 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?'} %>
...