Relationships... not the personal kind!

Hello all,

I’m very new to Rails and I love it so far. However, there are some
things that aren’t so clear to me.

Let’s say a blog post can have many comments, and a comment can only
belong to one post. A user can have many posts and many comments as
well. (this part makes perfect sense):

class Comment < ActiveRecord::Base
belongs_to :posting
belongs_to :user
end

class Posting < ActiveRecord::Base
has_many :comments
belongs_to :user
end

class User < ActiveRecord::Base
has_many :comments
has_many :postings
end

In the comment_controller, how would I actually go about saving the
comment with the appropriate foreign keys of the posting and user. In
the comments table I have the appropriate columns (posting_id,
user_id).

Here’s what I have in the comment_controller for creating a new comment:

def new
@comment = Comment.new
end

def create
@comment = Comment.new(params[:comment])
@comment.users_ip = request.remote_ip
@comment.users = session[:user] <— Doesn’t work… stumped
@comment.posting = @posting <---- Where I’m stumped again
if @comment.save
flash[:notice] = ‘Comment was successfully created.’
redirect_to :action => ‘list’
else
render :action => ‘new’
end
end

Am I close at all? Is using the session[:user] the best way to get the
logged in user to associate the comment and user?

Thank you in advanced,
Ted

On Jan 19, 2006, at 2:15 PM, Ted Oleander wrote:

belongs_to :posting
has_many :postings
def new
redirect_to :action => ‘list’
else
render :action => ‘new’
end
end

Looks pretty close to me!

One thing to keep in mind when you make use of associations is that
whatever the symbol you use to define the association, that symbol is
now the “key” in to how Rails creates all of the automagical methods.

For example, you’ve defined Comment belongs_to :user. Note that
you’ve used a singular ‘user’, so the automagical methods created by
rails will be singular in this case. Thus, your “Doesn’t work…
stumped” line up above should read:

@comment.user = session[:user]

Second, I’m not sure where the @posting variable is coming from. Do
you have a before_filter that sets it up somewhere? Otherwise,
@posting is going to be nil, and that will be the equivalent of
unsetting the association. If you have the id of the posting in
the params, for example, you could just do this:

@comment.posting_id = params[:id]

Or if you have the actual object, e.g. @posting = Posting.find(params
[:id]) then the code you’ve written above will work fine.

Am I close at all? Is using the session[:user] the best way to get the
logged in user to associate the comment and user?

Thank you in advanced,
Ted

You’re welcome, and good luck!

Duane J.
(canadaduane)
http://blog.inquirylabs.com/

Thanks Duane. That cleared some issues up for me.

For some reason though this doesn’t work:
@comment.user = session[:user]

…but this does:
@comment.user_id = session[:user]

Even though it works the above way, is it the right way?

The comment issue: When the posting id comes into the “new” action for
the comment, it comes in like this from
http://localhost:3000/listings/
http://localhost:3000/comments/new/1 ← For post number 1
http://localhost:3000/comments/new/2 ← For post number 2
etc…

I’ve tried adding the following in the ‘new’ action in the Comments
controller:

posting_id = Comment.new(params[:id]) # Always is saved as ‘1’
@comment.posting_id = posting_id

I’ve changed the params[:id] to params[:posting_id] but I’ve had no
luck with that.

Thanks,
Ted

Ted,

I had a similar issue recently. I have no idea if this is ‘the best’
way to accomplish it, but it works.

In your ‘new’ action you could grab the id parameter passed in and
place it in the session:

session[:posting_id] = params[:id]

Then in your create action you could do access it like this:

@comment.posting_id = session[:posting_id]

Be sure to erase the session variable after saving.

There has to be a better way though. All these session variables could
really slow the system down over time.

Hope that helps a little!
-Dave

On Jan 20, 2006, at 12:05 PM, Ted Oleander wrote:

Thanks Duane. That cleared some issues up for me.

For some reason though this doesn’t work:
@comment.user = session[:user]

…but this does:
@comment.user_id = session[:user]

Are you storing the ID of the user in the session? Both ways are
valid, you just have to be sure of which convention you’re using :slight_smile:
It’s good (in general) to add an _id to the end if it’s an id. E.g.:

@comment.user_id = session[:user_id]

Makes it more consistent, but this requires that you set the
session’s user_id somewhere. Where are you setting the session
[:user]? I would switch it to session[:user_id] = if that
is indeed what is going on, just for readability’s sake. However, if
it works, it works.

controller:

posting_id = Comment.new(params[:id]) # Always is saved as ‘1’
@comment.posting_id = posting_id

I’ve changed the params[:id] to params[:posting_id] but I’ve had no
luck with that.

That code looks somewhat circuitous :slight_smile:

Try this:

@comment = Comment.new(params[:comment])
@comment.posting_id = params[:id]
if @comment.save
# send success message etc.
end

This assumes that you’re using the FormHelper methods in a standard
way, e.g. in your view:

<%= start_form_tag :action => ‘new’, :id => params[:id] %>
Your N.: <%= text_field ‘comment’, ‘name’ %>

Comment: <%= text_field ‘comment’, ‘body’ %>
… etc …
<%= end_form_tag %>

Note that :id => params[:id] is necessary for postback forms (like
yours) so that the Posting id is retained when the comment is submitted.

Duane J.
(canadaduane)
http://blog.inquirylabs.com/