How to pass an object in a form

as the user is available in the controller directly through a method,
there is no need to use a hidden field or pass it with the form in any
other way. Besides, this would enable users to play with the form data
and e.g. post comments under another users id.

Instead, user this approach:
def create
@comment = current_user.comments.build(params[:comment])
  if @comment.save
    # .... and so on, usual stuff
  end
end

Buy building the object though the associations #build method, the
user_id column is automatically filled in, and for the user there is
no way of hacking another id into this.

This approach should be used in othert similar situations with nested
resources as well. it makes the code cleaner and more secure in
general.

Thanks for the help.

Ok so now I don't use any field and expect the controller to know about
the user. I did a test, user1 is loged in when posting.

This is the POST generated to create a comment:

Processing CommentsController#create (for 127.0.0.1 at 2008-03-05
14:57:51) [POST]

Session ID:
BAh7C....

Parameters: {
"program_id"=>"1",
"commit"=>"Create",
"authenticity_token"=>"ff...",
"action"=>"create",
"controller"=>"comments",
"comment"=>{"body"=>"A new comment by user1"}}

...

Comment Create (0.000000)←[0m ←[0m
INSERT INTO `comments` (`program_id`, `updated_at`, `body`, `user_id`,
`created_at`) VALUES(1, '2008-03-05 14:57:51', 'A new comment by
user1', NULL, '2008-03-05 14:57:51')

...

So as we see the user_id is not included in the parameters at all. And
from the last part we see that the VALUE for user_id is NULL. So I'm
still facing the same problem that let me to try the hidden field.

Hints?

what does your create action look like now?

also. slight correction as also program is a parent of the comment:

@program = Program.find(params[:progam_id])
@comment = @program.comments.build(params[:comment])
@comment.user = current_user
if @comment.save
#.....

Hi,

@comment.user = current_user

I think that line was the final hint. But then I realized that at this
point I just want to see the user name and so far I was dealing with the
id, so I would need to look for the right name based on the user id.

So, I changed the comments model so that is contains a created_by string
instead of a reference to user.

Then I ended up with:

  def create
    @comment = @program.comments.build(params[:comment])
    @comment.created_by = current_user.login
  ...

And in the view I use:

<% for comment in @comments %>
  <tr>
    <td><%=h comment.created_by %></td>
    ....

And well that seems to be going fine. I can retrieve now from each
comment the name of the user that created it. That's what I was looking
for (today :sunglasses:

I think this should do it...

Thanks a lot!
(I don't know what I would do without this forum :wink:

Hi,

If you want to be more DRY in your template, you can do:

in create.rhtml:
<% render :partial => 'comment_strip', :collection => @comments -%>

in _comment_strip.rhtml partial:
<% comment ||= comment_strip -%>
<tr>
  <td><%=h comment.created_by %></td>
  ...

One question for you.. what if the user changes their name?

Robby

One question for you.. what if the user changes their name?

Robby

I guess the question is for me since I said I'm happy with username at
this point. Yep that is a valid point. It would be safer to use the ID.

At this point I can move forward with the username. They wont change
them since I don't let them do it :sunglasses:

But ID should be the one to use.

Cheers

another consideration is if you want to allow users to delete their
own comments. If you just store the username for a comment, you can't
allow this, unless your usernames are unique and can't be changed. So
yes, storing the id for the user is much better.

You might also want to check out the acts_as_commentable plugin which
provides a porlymorphic comment class, allowing you to assign comments
to various different models.

You can also use the userstamp plugin which will assign the currently
logged in user's id to the object being created if your model contains
a 'created_by' column in the associated database table. I'm a big fan
of this option, since I often like to record the id of the user that
created or updated an object.

Mike

Nice discussion you guys have here.

What if you have two levels of nesting? Take the following three
models:

Driver
  has_many :cars
  has_many :mugshots, :class_name => 'Image', :as => :asset

Car
  belongs_to :driver
  has_many :photos, :class_name => 'Image', :as => :asset

Image
  belongs_to :asset, :polymorphic => true
  has_attachment :content_type => :image, # using attachment_fu

How would you code the form to make mass-assignment work?