1

我正在阅读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() 有两个参数。他们要解决什么问题以及为什么有必要这样做?

谢谢,迈克

4

2 回答 2

16

实际上,在您的示例中,您form_for使用一个参数(即数组)进行调用。如果您查看文档,您将看到它期望的参数:form_for(record, options = {}, &proc). 在这种情况下,arecord可以是 ActiveRecord 对象,也可以是 Array(它也可以是 String、Symbol 或类似 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)})

当然,还有更多的故事,但应该足够了,掌握这个想法。

于 2012-05-17T08:30:50.780 回答
1

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

/articles/1/comments

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

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

/comments

在控制器中,您将无法知道评论属于哪篇文章。

请注意,要使其正常工作,您需要在路由文件中定义嵌套资源

于 2012-05-17T07:56:47.130 回答