Невозможно отобразить ошибки вложенного ресурса на странице показа родительского ресурса. - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть базовое приложение для блогов с постами и комментариями. Я хотел бы позволить пользователям комментировать сообщение из post#show, и я не совсем уверен, как представить ошибки проверки комментария к сообщению.

Код ниже размещает комментарии под сообщениями и успешно создает комментарии. Проблема, когда при сбое проверки (например, при пустом комментарии) посетитель перенаправляется на страницу публикации, но сообщения об ошибках комментария теряются.

Прямо сейчас CommentsController#create перенаправляет пользователя на post, который он просматривал. В качестве альтернативы я попытался render 'posts/show' вместо перенаправления, но в конечном итоге страница отображается на posts/1/comments вместо posts/1.

Буду признателен за любую помощь в получении ошибок для проверок комментариев, отображаемых в шаблоне сообщений / шоу.

Маршруты

# config/routes.rb
Rails.application.routes.draw do
  resources :posts do
    resources :comments, only: [:create]
  end
end

Модель

class Comment < ApplicationRecord
  belongs_to :post  
  validates :content, presence: true, length: { in: 6..20 }
end

class Post < ApplicationRecord
  has_many :comments
end

Контроллеры

# app/controllers/posts_controller.rb
class PostsController < ApplicationController
  def show
    @post = Post.find(params[:id])
  end
end


# app/controllers/comments_controller.rb
class CommentsController < ApplicationController
  def create
    @post = Post.find(params[:post_id])
    @comment = @post.comments.build(comment_params)

    if @comment.save
      # SAVE works fine
      redirect_to @post, notice: 'Comment was successfully created.'
    else
      # ERROR displays nothing on the post show page
      redirect_to @post
    end
  end

  private

  def comment_params
    params.require(:comment).permit(:content, :post_id)
  end
end

1024 * Просмотры * # app/views/posts/show.html.erb <p id="notice"><%= notice %></p> <p> <strong>Title:</strong> <%= @post.title %> </p> <h2>Comments</h2> <table> <thead> <tr> <th>Content</th> </tr> </thead> <tbody> <% @post.comments.each do |comment| %> <tr> <td><%= comment.content %></td> </tr> <% end %> </tbody> </table> <br> <h3>New Comment</h3> <%= render 'comments/form', post: @post, comment: @post.comments.build %> # app/views/comments/_form.html.erb <%= form_with(model: [post, comment], local: true) do |form| %> <% if comment.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(comment.errors.count, "error") %> prohibited this comment from being saved:</h2> <ul> <% comment.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> </div> <% end %> <div class="field"> <%= form.label :content %> <%= form.text_field :content %> </div> <div class="actions"> <%= form.submit %> </div> <% end %> Примечание: я стараюсь по возможности избегать accepts_nested_attributes_for, так как для более сложных случаев использования я нахожу это крайне запутанным.

1 Ответ

0 голосов
/ 06 сентября 2018

Вы не видите сообщение об ошибке, потому что при неудачной попытке сохранения вы перенаправляете на другой контроллер / действие; несохраненный @comment объект не только исчезает, но и перезаписывается в слое представления при визуализации формы комментария. Попробуйте отобразить представление posts/show в действии CommentsController#create.

if @comment.save
  # SAVE works fine
  redirect_to @post, notice: 'Comment was successfully created.'
else
  render 'posts/show'
end

Чтобы это работало, вам также нужно переместить создание нового комментария из вида в PostsController#show действие.

# app/controllers/comments_controller.rb
class PostsController < ApplicationController
  def show
    @post = Post.find(params[:id])
    @comments = @post.comments
    @comment = Comment.new(post: @post)
  end
end

Выполните итерацию на @comments, загруженном в контроллер. Новый комментарий не должен быть среди них. При визуализации формы используйте переменную @comment. Не забудьте связать новый комментарий с сообщением перед его сохранением.

<h2>Comments</h2>

<table>
  <thead>
    <tr>
      <th>Content</th>
    </tr>
  </thead>

  <tbody>
    <% @comments.each do |comment| %>
      <tr>
        <td><%= comment.content %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<br>
<h3>New Comment</h3>

<%= render 'comments/form', post: @post, comment: @comment %>

Таким образом, posts/show представление должно работать с обоими действиями контроллера; состояние @comment объекта, наряду с его ошибками, должно быть сохранено после попытки сохранения.

...