Forum: Ruby on Rails Relationships... not the personal kind!

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Ted Oleander (Guest)
on 2006-01-19 23:53
(Received via mailing list)
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
Duane J. (Guest)
on 2006-01-20 18:38
(Received via mailing list)
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
*un*setting 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/
Ted Oleander (Guest)
on 2006-01-20 21:45
(Received via mailing list)
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
Dave H. (Guest)
on 2006-01-20 21:54
(Received via mailing list)
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
Duane J. (Guest)
on 2006-01-21 00:44
(Received via mailing list)
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 :)
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] = <the 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 :)

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' %><br/>
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/
This topic is locked and can not be replied to.