【发布时间】:2016-04-14 19:34:00
【问题描述】:
当无法通过comments#create 保留评论时,我想在articles\view.html.erb 上显示新@comment 的验证错误。
TLDR,我使用Getting Started 教程和rails 4.2.6 和ruby 2.2.3 创建了一个博客。
一个博客有很多文章,每篇文章都有很多评论。
按照教程,发布新评论的表单位于articles\view.html.erb 中,并保留在comments#create 中。发布新评论后,它会再次重定向到articles#show。
class Article < ActiveRecord::Base
has_many :comments
validates :title, presence: true, length: { minimum: 5 }
end
class Comment < ActiveRecord::Base
belongs_to :article
end
我使用相同的视图 - articles/show.html.erb - 显示文章及其cmets并发布新评论
<p><strong>Title:</strong><%= @article.title %></
<p><strong>Text:</strong><%= @article.text %></p>
<h2>Comments</h2>
<% @article.comments.each do |comment| %>
<p><strong>Commenter:</strong><%= comment.commenter %></p>
<p><strong>Comment:</strong><%= comment.body %></p>
<% end %>
<h2>Add a comment:</h2>
<%= form_for([@article, @article.comments.build]) do |f| %>
<p><%= f.label :commenter %><br><%= f.text_field :commenter %></p>
<p><%= f.label :body %><br><%= f.text_area :body %></p>
<p><%= f.submit %></p>
<% end %>
<%= link_to 'Edit', edit_article_path(@article) %> |
<%= link_to 'Back', articles_path %>
通过articles_controller
def show
@article = Article.find(params[:id])
end
和comments_controller 发表新评论
def create
@article = Article.find(params[:article_id])
@comment = @article.comments.create(comment_params)
redirect_to article_path(@article)
end
它按预期工作:)
这是我的问题开始的地方......
我决定进一步向 Comment 模型添加一些验证
class Comment < ActiveRecord::Base
belongs_to :article
validates :commenter, presence: true
validates :body, presence: true
end
并在保存失败时显示注释错误。
首先,我尝试通过文章模型显示错误
<% if @article.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@article.errors.count, "error") %> prohibited this article from being saved:</h2>
<ul><% @article.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %></ul>
</div>
<% end %>
然后我尝试在articles_controller 中使用全局变量@comment
def show
@article = Article.find(params[:id])
@comment = @article.comments.build
end
<% 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 |msg| %>
<li><%= msg %></li>
<% end %></ul>
</div>
<% end %>
它也没有用。
据我了解,这种方式不起作用,因为当我提交 新评论 时,我会重定向到文章显示操作 redirect_to article_path(@article) - 无论是成功还是不保存新评论评论 - 因此创建了一个新的评论实例,用它的错误覆盖前一个。
我最好的解决方案是使用带有错误消息的 flash 属性。看起来是这样的
comments_controller
def create
@article = Article.find(params[:article_id])
@comment = @article.comments.create(comments_params)
redirect_to article_path(@article), flash: {new_article_errors: @comments.errors.full_messages}
end
articles/show.html.erb
<% unless flash[:new_comment_errors].nil? %>
<div id="error_explanation">
<h2>
<%= pluralize(flash[:new_comment_errors].count, "error") %> prohibited this comment from begin saved:
</h2>
<ul>
<% flash[:new_comment_errors].each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
但这也不是最好的解决方案。它会显示错误但会丢失已填写的值(表格清晰)。
我需要通过redirect_to 传递@comment 吗? 像这样的
comments_controller
def create
@article = Article.find(params[:article_id])
@comment = @article.comments.build(comments_params)
if @comment.save
redirect_to article_path(@article)
else
redirect_to article_path(:comment => params[:comment] )
end
end
article_controller
def show
@article = Article.find(params[:id])
@comment = @article.comments.build
@comment.valid? if params[:comment]
end
现在我收到了No route matches 错误。我应该创建一个接收params[:comment] 的新操作吗?或编辑显示路线以接收它?
我已经阅读了Nested model validation - errors don't show,但没有帮助,因为他们建议在comments_controller 中创建新操作,而我不希望这样做(新帖子表单 需要在article/show.html.erb)。
Nested Model Form Part 1 和 Nested Model Form Part 2 也没有帮助。
感谢您的宝贵时间和帮助!
【问题讨论】:
-
谢谢@Vucko,我会检查的。
-
这不是重复的问题@Vucko。我编辑了问题以添加更多信息并避免可能的重复。
标签: ruby-on-rails ruby ruby-on-rails-4