我有一篇文章模型和评论模型。我目前有两个单独的表单来创建新的评论:一个允许用户指定他们的评论所针对的文章的名称,另一个允许用户在文章显示视图下面为该文章创建新评论。我在第一种情况下使用form_for @comment,在第二种情况下使用form_for [@ article,@ comment]。当用户将文章名称指定为字符串时,我会在保存评论之前将其转换为文章ID。
我的路线是
resources :comments
resources :articles do
resources :comments
end
对于第二种形式,如何重定向到失败的注释保存文章(应显示验证和错误)?对于第一个表单,我只是重定向到主页,因为这是我的第一个评论表单。
另外,我在第一个表单上验证了文章名称字段不能为空。如何删除第二个表单的验证,因为用户不需要指定文章名称?
我在comments_controller中的新函数处理两种形式。如何确定控制器中提交的表单?
提前致谢。
答案 0 :(得分:2)
实际上,重定向不是去这里的方式,我会说。 Rails中的错误和验证处理通常与您使用经过验证的对象在create
或update
方法中重新呈现表单的方式相同,而不是实际重定向到new
或edit
页面。
至于保存两个版本的评论的问题,我会在两个版本中使用form_for @comment
。转储嵌套表单版本使用表单中给定的文章字符串模拟用户的行为。这样你就可以省去很多if-else语句。
至于验证错误部分的渲染,你可以简单地检查你的params中是否有article_id(这意味着你通过给定的文章创建/更新评论)或者没有(这意味着你有第一个版本)。
一些代码要详细说明:
# routes.rb
# keep the routes as they are
resources :comments
resources :articles
resources :comments
end
# CommentsController.rb
def new
# don't use build
@comment = Comment.new
# get the article, if there is one to get
@article = Article.find(params[:article_id]) if params[:article_id]
# get all articles if there is no single one to get
@articles = Article.all unless params[:article_id]
end
def create
# fetch article id from title (in any case)
# I'm assuming here
params[:comment][:article_id] = fetch_article_id_from_title(params[:comment][:article_title])
@comment = Comment.new(params[:comment])
if @comment.save
redirect_to everything_worked_fine_path
else
# render the new view of the comments and actually
# forget the article view. Most sites do it like this
render action: "new"
end
end
# form partial
<%= form_for @comment do |f| %>
<% if @article %>
# there's an article to save this comment for
<%= f.hidden_field :article_title, @article.title # I'm assuming here
<% else %>
# this means there's no particular article present, so let's
# choose from a list
<%= f.select ... %>
<% end %>
<% end %>
希望这有帮助。