2012-05-17 3 views
1

Я читаю Beginning Rails 3. Он создает блог с пользователями, которые могут публиковать статьи, а также публиковать комментарии к этим статьям. Они выглядят так:Несколько параметров для form_for()

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 

в приложение/просмотров/комментариев/new.html.erb есть форма, которая начинается так:

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

Моя путаница заключается в том, почему form_for() имеет два параметра , Что они решат и почему они необходимы?

спасибо, микрофон

+0

Итак ... мы помогли, или вам все еще нужно что-нибудь? :) – Ernest

ответ

16

Фактически, в вашем примере вы вызываете form_for с один параметр (который является массивом). Если вы проверите документацию, вы увидите параметры, которые она ожидает: form_for(record, options = {}, &proc). В этом случае record может быть объектом 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)}) 

Конечно, есть больше к истории, но оно должно быть достаточно, чтобы понять эту идею.

1

Это форма для комментируя статью. Итак, вам, вам нужен Article, который вы комментируете (@article) и новый экземпляр Comment (@article.comments.new). Форма действие для этой формы будет что-то вроде:

/articles/1/comments 

Он содержит id статьи вы комментируя, которые вы можете использовать в вашем контроллере.

Если опустить @article так: form_for @article.comments.new, воля формы действий выглядит следующим образом:

/comments 

В контроллере вы не имели бы никакого способа знать, к какой статье относится комментарий.

Обратите внимание, что для этого вам необходимо определить nested resource в файле маршрутов.