Rails:创建用户指定关联的表单和基于当前资源的表单

时间:2012-10-19 07:45:12

标签: ruby-on-rails ruby-on-rails-3

我有一篇文章模型和评论模型。我目前有两个单独的表单来创建新的评论:一个允许用户指定他们的评论所针对的文章的名称,另一个允许用户在文章显示视图下面为该文章创建新评论。我在第一种情况下使用form_for @comment,在第二种情况下使用form_for [@ article,@ comment]。当用户将文章名称指定为字符串时,我会在保存评论之前将其转换为文章ID。

我的路线是

resources :comments

resources :articles do
  resources :comments 
end

对于第二种形式,如何重定向到失败的注释保存文章(应显示验证和错误)?对于第一个表单,我只是重定向到主页,因为这是我的第一个评论表单。

另外,我在第一个表单上验证了文章名称字段不能为空。如何删除第二个表单的验证,因为用户不需要指定文章名称?

我在comments_controller中的新函数处理两种形式。如何确定控制器中提交的表单?

提前致谢。

1 个答案:

答案 0 :(得分:2)

实际上,重定向不是去这里的方式,我会说。 Rails中的错误和验证处理通常与您使用经过验证的对象在createupdate方法中重新呈现表单的方式相同,而不是实际重定向到newedit页面。

至于保存两个版本的评论的问题,我会在两个版本中使用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 %>

希望这有帮助。