我有一个带有帖子和评论的基本“博客”应用程序。我想允许用户对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
# 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
,因为对于更复杂的用例,我感到非常混乱。
答案 0 :(得分:2)
您不会看到错误消息,因为在失败的保存尝试中,您将重定向到其他控制器/操作;未保存的@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
对象的状态及其错误。