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?