Parameter passing

I have this 2 models in the rails application.

class Project
has_many :comments

class Comments
belongs_to :Project

i.e in the Comment table I have column name project_id.

The model is such that for each projects there are many comments. Now I
want the user to have the facility for adding new comments for any
existing project.

Now my question is that how do I pass the existing project_id for adding
a new comment in the comments table ?

Firstly,

  1. Comments should be Comment. Model class names should be singular.
  2. The model should belongs_to :project, not :Project. I’m not sure if this makes a difference, but I think it reads better this way.

Now in your controller if you already have an existing project object initialized:

@project.comments.build(params[:comment])

This works exactly like Comment.new(params[:comment].merge({ :project_id => @project.id}), just without all the ugliness.

Oh I should re-enforce the fact that build does not create a comment object, it merely initializes a new one. You will still have to save it. That is, unless you change build to create, in which case it’ll just create it.

My main problem is Im not able to intialize the project object. Im
explaining in detail

In my view/project/myprojects.rhtml

<%= link_to 'Edit'
,{:action=>'newcomment',:controller=>'project',:id=>project}%>

Using this file for the user to enter a new comment
view/project/newcomment.rhtml view

<%= render :partial => 'users/user_tabs' %><br>

<%= error_messages_for :project %>
<% form_for(:project, :url => {:controller => "project", :action =>
"editcomment" },
                      :html => { :multipart => true, :name => "ref_form"
}) do |f| -%>
  <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0>
            <TR>
              <TD HEIGHT=15 COLSPAN=11></TD>
              <TD WIDTH=6 HEIGHT=15></TD>
            </TR>

            <TR>
              <TD HEIGHT=25>Reference Comment</TD>
              <TD HEIGHT=25 align="left"><%= text_area "comment", :cols
=> 20, :rows => 5 %></TD>
            </TR>
            href="javascript:document.dyna_form.submit()";><img
src="/images/create.jpg" /></a></TD> -->
       <TD><%= image_submit_tag("/images/create.jpg")%>
              <TD>&nbsp;</TD>
              <TD></TD>
            </TR>

</table>
<% end %>

controllers/project_controller.rb

def newcomment
@project=Project.find(params[:id])
end

def editcomment
  @project.comments.build(params[:comment])
end

Now Im failing to pass the initialized @project object inside
editcomment method

-Saurav

Im passing the project id parameter using
Ryan Bigg wrote:

Whether or not you opt for RESTful routing as Ryan suggests, you need
to understand that instances of the controllers live only as long as
they are necessary for responding to a request. In practical terms
that means that you cannot set an instance variable in one action and
expect to see it available in another. That appears to be what you've
done in newcomment (set @project) and editcomment (build using
@project). Since the ProjectsController instance goes away after the
newcomment form renders, @project also no longer exists, so
editcomment must make it's own.

Also, don't miss the point that Ryan made about build -- it's similar
to 'new' with some initializing done under the covers. It does not
save anything to the db. You'll need create to do that.

def newcomment
@project=Project.find(params[:id])
end

def editcomment
@project=Project.find(params[:id])
@project.comments.create(params[:comment])
end

Just one comment about conventions, too. Typically 'edit' is used to
retrieve an instance that already exists and return a form that can be
used to make changes; create is used to save a new instance and update
is used to persist changes. You are not required to follow that but
you will find your code more consistent and easier to follow if you
do.

Thanx for the information. It was a great help