I want to create a comment form at the bottom of a blog entry. The problem is that it doesn't save the blog_id so while the comment is created, it isn't assigned a blog_id. I thought that by having this line:
@new_comment = @blog.comments.build(params[:comment])
that it would work but it doesnt. This is what I have:
blog#show
def show
@blog = Blog.find(params[:id])
@new_comment = @blog.comments.build(params[:comment])
end
blog#form
...
<%= semantic_form_for @new_comment do |f| %>
<%= f.input :name %>
<%= f.input :content, :label => "Comment", :input_html => { :rows => 6, :class => "xxlarge" } %>
<div class="pull-right"><%= f.commit_button :button_html => {:class => "primary"}, :label => "Submit" %></div>
<% end %>
blog.rb
accepts_nested_attributes_for :comments
comments controller
def create
@comment = @blog.comments.build(params[:comment])
if @comment.save
redirect_back_or show_blog_path(@blog)
else
redirect_to show_blog_path(@blog)
end
end
EDIT:
I nested the form inside the @blog by doing:
<%= semantic_form_for @blog do |f| %>
<%= f.semantic_fields_for :comments do |ff| %>
<%= ff.input :name %>
<%= ff.input :content, :label => "Comment", :input_html => { :rows => 6, :class => "xxlarge" } %>
<% end %>
<div class="pull-right"><%= f.commit_button :button_html => {:class => "primary"}, :label => "Submit" %></div>
<% end %>
and changed the blogs#show to:
@blog = Blog.find(params[:id])
@blog.comments.build
@comments = Comment.where(:blog_id => @blog.id)
Everything works fine, but now after I submit the comment, the comment shows up twice. It shows up in the comments section where it is supposed to and it also shows up as a prepopulated comments form on top of a new comments form. So you see the content of the blog, the prepopulated comment form that I just submitted, a new comments form, and the comment in the display comments section.
I don't know what that it.
You are not referencing the parent object in your form. Yes, you have initialised @new_comment
which references the current @blog
, but the comment form does not specify this. If you inspect the params passed to create action of comments controller, you are most likely to find no bold_id
being passed.
Try doing
f.hidden :blog
in the comment form.
Or, if you do not wish to have a hidden field as such, then you can have a nested form as
semantic_form_for [@blog, @new_comment] do |f|
But, this requires your routes file to have paths for comments to be nested under blogs, something as(lets take only the create action for now)
resources :blogs do
resources :comments, :only => [:create]
end
This is required as the form's post is directed to blog_comments_path.
Hope this helps.
EDIT : This is how I suggest implementing it (ymmv, so, please be clear if it satisfies your needs) -
blogs#show
as :
@blog = Blog.find(params[:id])
@now_comment = @blog.comments.build
@comments = @blog.comments # existing comments u might wanna show below the post
The form as :
= semantic_form_for [@blog, @new_comment] do |f|
# input for name and content
Routes - nested as shown above
comments#create
as : (blog_id is passed as params too. So, you can find the blog and build a comment based on comment params for that blog and then save it)
@blog = Blog.find(params[:blog_id])
@comment = @blog.comments.new(params[:comment])
@comment.save