I have a two-part somewhat noob question about form_for and nested resources. Let's say I'm writing a blog engine and I want to relate a comment to an article. I've defined a nested resource as follows:
map.resources :articles do |articles|
articles.resources :comments
end
The comment form is in the show.html.erb view for articles, underneath the article itself, for instance like this:
<%= render :partial => "articles/article" %>
<% form_for([ :article, @comment]) do |f| %>
<%= f.text_area :text %>
<%= submit_tag "Submit" %>
<% end %>
This gives an error, "Called id for nil, which would mistakenly etc." I've also tried
<% form_for @article, @comment do |f| %>
Which renders correctly but relates f.text_area to the article's 'text' field instead of the comment's, and presents the html for the article.text attribute in that text area. So I seem to have this wrong as well. What I want is a form whose 'submit' will call the create action on CommentsController, with an article_id in the params, for instance a post request to /articles/1/comments.
The second part to my question is, what's the best way to create the comment instance to begin with? I'm creating a @comment in the show action of the ArticlesController, so a comment object will be in scope for the form_for helper. Then in the create action of the CommentsController, I create new @comment using the params passed in from the form_for.
Thanks!
-
Include a hidden
article_id
form field, populated with the article's ID. On submission, the comment should set up the association all by itself.Dave Sims : That sorta defeats the idea of using the nested resource path /articles/[id]/comments doesn't it? -
Basically you are doing the same as in this guide with your second try, only thing is that you use the same field name for the post text and the comment text.
Although I do not understand why this is not working, it seems easy to change the comment field name into comment instead of text. So
<%= f.text_area :comment %>
is not matching with the text field of post any more.Looking at the guide seems reasonable as well, since they tend to achieve the result you are looking for with your example.
For your second question: that is also explained in the guide. Using
@comment = Comment.new
for the new action and
@comment = Comment.new(params[:comment]) @comment.save
for the create actions, seem their way of working.
-
You don't need to do special things in the form. You just build the comment correctly in the show action:
class ArticlesController < ActionController::Base .... def show @article = Article.find(params[:id]) @new_comment = @article.comments.build end .... end
and then make a form for it in the article view:
<% form_for @new_comment do |f| %> <%= f.text_area :text %> <%= f.submit "Post Comment" %> <% end %>
by default, this comment will go to the
create
action ofCommentsController
, which you will then probably want to putredirect :back
into so you're routed back to theArticle
page.
0 comments:
Post a Comment