form_for()的多个参数

时间:2012-05-17 07:45:08

标签: ruby-on-rails

我正在阅读Beginning Rails 3.它创建了一个博客,用户可以发布文章并发布评论到这些文章。它们看起来像这样:

    class User < ActiveRecord::Base
      attr_accessible :email, :password, :password_confirmation
      attr_accessor :password

      has_many :articles, :order => 'published_at DESC, title ASC',
                          :dependent => :nullify
      has_many :replies, :through => :articles, :source => :comments

    class Article < ActiveRecord::Base
      attr_accessible :body, :excerpt, :location, :published_at, :title, :category_ids

      belongs_to :user
      has_many :comments

    class Comment < ActiveRecord::Base
      attr_accessible :article_id, :body, :email, :name
      belongs_to :article

在app / views / comments / new.html.erb中有一个表单,其开头如下:

    <%= form_for([@article, @article.comments.new]) do |f| %>

我的困惑在于为什么form_for()有两个参数。他们解决了什么,为什么有必要?

感谢, 麦克

2 个答案:

答案 0 :(得分:16)

实际上,在您的示例中,您使用一个参数(即Array)调用form_for。如果您查看文档,您将看到它所期望的参数:form_for(record, options = {}, &proc)。 在这种情况下,record可以是ActiveRecord对象,也可以是数组(它也可以是像ActiveRecord一样嘎嘎叫的字符串,符号或对象)。你什么时候需要传递一个数组呢?

最简单的答案是,当您拥有嵌套资源时。与您的示例中一样,您已定义Article has many Comments关联。当您调用rake routes并且具有正确定义的路由时,您将看到Rails已为您定义了嵌套资源的不同路由,例如:article_comments POST /article/:id/comments

这很重要,因为你必须为你的表单标签创建有效的URI(不是你,Rails会为你做)。例如:

form_for([@article, @comments])

你对Rails说的是:“嘿Rails,我给你作为第一个参数的对象数组,因为你需要知道这个嵌套资源的URI。我想在这个表单中创建新的注释,所以我只会给你@comment = Comment.new的初始实例。请为这篇文章创建此评论:@article = Article.find(:id)。“

这与写作大致相似:

form_for(@comments, {:url => article_comments_path(@aticle.id)})

当然,故事还有更多内容,但这应该足以掌握这个想法。

答案 1 :(得分:1)

这是评论文章的表格。所以,您需要Article评论(@article)和新的Comment实例(@article.comments.new)。此表单的表单操作类似于:

/articles/1/comments

它包含您正在评论的文章的id,您可以在控制器中使用该文章。

如果省略@article这样的结果:form_for @article.comments.new,表单操作将如下所示:

/comments

在控制器中,您无法知道评论所属的文章。

请注意,为此,您需要在路线文件中定义nested resource