I’m reading Beginning Rails 3. It creates a blog with Users who can post Articles and also post Comments to these Articles. They look like this:
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
in app/views/comments/new.html.erb there’s a form which begins like this:
<%= form_for([@article, @article.comments.new]) do |f| %>
My confusion lies in why form_for() has two parameters. What do they resolve to and why are they necessary?
thanks,
mike
Actually, in your example, you are calling
form_forwith one parameter (which is Array). If you check the documentation you will see parameters it expects:form_for(record, options = {}, &proc).In this case a
recordcan be ActiveRecord object, or an Array (it can be also String, Symbol, or object that quacks like ActiveRecord). And when do you need to pass it an Array?The simplest answer is, when you have a nested resource. Like in your example, you have defined
Article has many Commentsassociation. When you callrake routes, and have correctly defined routes, you will see that Rails has defined for you different routes for your nested resource, like:article_comments POST /article/:id/comments.This is important, because you have to create valid URI for your form tag (well not you, Rails does it for you). For example:
What you are saying to Rails is: “Hey Rails, I am giving you Array of objects as a first parameter, because you need to know the URI for this nested resource. I want to create new comment in this form, so I will give you just initial instance of
@comment = Comment.new. And please create this comment for this very article:@article = Article.find(:id).”This is roughly similar to writing:
Of course, there is more to the story, but it should be enough, to grasp the idea.