Form_for - Child object - how to set parent id

Hi All,

I am just trying to learn ruby/rails so please don’t flame me if this is
a stupid question.

As a learning project I decided to create my own blog using ROR. I have
created a controller that shows paged blog entries, and below each blog
is a list of comments along with a form alowing the user to add a new
comment.

To create the form for the comment entry I used form_for which worked
fine. However I need to somehow set the blog Id on the comment that is
entered into that form. Here is the rhtml for the list:

<% for blog in @blogs %>
<%=h blog.title %>
<%=h blog.date_entered.to_s(:long) %>
<%=h blog.body %>


<%=h
pluralize(blog.comments.size,“comments”) %>
<% for comment in blog.comments %>

<%=h comment.name %> said:

<%=h comment.body %>

<%=h
comment.date_entered.to_s(:long) %>


<% end %>

<%= error_messages_for ‘comment’ %>

Add your comment:
<% form_for :comment, :url => { :action => :add_comment } do
|form| %>


Name:
<%= form.text_field :name %>



E-Mail:
<%= form.text_field :email %>



Comments:
<%= form.text_area :body, :rows => 3, :cols => 40 %>


<%= submit_tag “Add Comment” , :class => “submit” %>
<% end %>


<% end %>

So you can see I have a form for block to handle the comments entry -
but if I have multiple blogs on a single page how can I specify that
this particular comment relates to blog X? If I only have one blog per
page I can get away with storing the blog id in the session, but this
seems a bit messy.

If I have not made this clear please let me know and I will try to
clarify.

Thanks,

D.

Anyone got any ideas on this - please?

D L wrote:

So you can see I have a form for block to handle the comments entry -
but if I have multiple blogs on a single page how can I specify that
this particular comment relates to blog X? If I only have one blog per
page I can get away with storing the blog id in the session, but this
seems a bit messy.

Hi D L,

(Welcome to Rails, by the way).

The key is to learn about how to specify the relationships between your
models. In your comment model, indicate that it’s parent object is a
Blog:

class Comment < ActiveRecord::Base

belongs_to :blog

end

Now, anytime you have a Comment object, you can use comment.blog to
“get back” to the parent blog object.

Does this help? If I misunderstood the question somehow, let me know.

Jeff

Have you thought about using Ajax to create the form on the fly, thereby
making the ownership of the comment clearer?

D L-3 wrote:

syntax like blog1.comments.create(:body => “A Comment”) and it all gets
def add_comment
does not seem to provide a way to add another parementer which I can

Hi D L,


Posted via http://www.ruby-forum.com/.


View this message in context:
http://www.nabble.com/form_for---Child-object---how-to-set-parent-id-tf2231865.html#a6193614
Sent from the RubyOnRails Users forum at Nabble.com.

Hi Jeff,

Thanks for the response, but I think you have misunderstood my question.

I understand how to link the objects and have done so with the
directives you mention (has_many, belongs_to etc). If I am working in
the ruby debugger/console I can add comments to my blogs etc using
syntax like blog1.comments.create(:body => “A Comment”) and it all gets
saved to the DB fine.

My problem is that I have a form in the view to create a new comment.
Again this works up to a point - the new comment is generated from the
params with now problems. However I intend to have multiple form_for
blocks within this view - one per blog/post to allow the user to add a
comment to any blog/post.
The problem is that I can not see any way to set the BlogId (parent) on
the comment. So I have code in my controller that looks like this:

def add_comment
@comment = Comment.new(params[:comment])
@comment.blog_id = ??? ← Where do I get this from???
if @comment.save
flash[:notice] = “Thank you for your comment”
end
list
render :action => ‘list’
end

So - how do I know which blog/post this comment relates to? The form_for
does not seem to provide a way to add another parementer which I can
pick up for the blog id. If I was only displaying one comment form per
page this would not be a problem because I could just put the blogid
into the session, and use it when the user clicks submit - but I have
more than one blog per page so I am stuck.

Any ideas?

Thanks,

D.

Jeff C. wrote:

D L wrote:

So you can see I have a form for block to handle the comments entry -
but if I have multiple blogs on a single page how can I specify that
this particular comment relates to blog X? If I only have one blog per
page I can get away with storing the blog id in the session, but this
seems a bit messy.

Hi D L,

(Welcome to Rails, by the way).

The key is to learn about how to specify the relationships between your
models. In your comment model, indicate that it’s parent object is a
Blog:

class Comment < ActiveRecord::Base

belongs_to :blog

end

Now, anytime you have a Comment object, you can use comment.blog to
“get back” to the parent blog object.

Does this help? If I misunderstood the question somehow, let me know.

Jeff
www.softiesonrails.com

 render :action => 'list'

end

From your view code I assume that you create one blank comment in your
controller and are trying to reuse that?

A better way may be to add a new_comment method to the blog model:

def new_comment
Comment.new( :blog=>self )
end

and then use

<%= form_for :comment, blog.new_comment, :url=>… %>
<%= form.hidden_field :blog_id %>

If you want to stick with the one-template-comment approach, do
something like

<%= hidden_field :comment, :blog_id, :value=>blog.id %>

Cheers,
Max

Max M. wrote:

 render :action => 'list'

end

From your view code I assume that you create one blank comment in your
controller and are trying to reuse that?

A better way may be to add a new_comment method to the blog model:

def new_comment
Comment.new( :blog=>self )
end

and then use

<%= form_for :comment, blog.new_comment, :url=>… %>
<%= form.hidden_field :blog_id %>

If you want to stick with the one-template-comment approach, do
something like

<%= hidden_field :comment, :blog_id, :value=>blog.id %>

Cheers,
Max

Hi Max - Thanks for your response - the hidden field idea looks like a
good way round my issue.

I did find another way around it - I replaced the form_for tag with:

<%= form_tag :action => :add_comment, :id => blog %>


Name:
<%= text_field “comment”, “name” %>


etc etc

And my controller code now looks like:

def add_comment
@comment = Comment.new(params[:comment])
@comment.blog_id = params[:id]
if @comment.save

Are there any gotcha’s with this? Should I do it the way you suggest,
rather than have I have done it?

Cheers,

D.