rmc will pay $5.00 to the first person to successfully answer the question:

When a user is browsing through a listing of a model, I'd like him to be able to, say, click on a button/link that will open a form that will allow the user to add a comment on the current record. I have already installed the acts_as_commentable plugin, done the migration of the Comments table, added the acts_as_commentable directive to the class (say, the class name is Task). I have read the tutorial/instruction in the TechKnow Zenze web site, but it doesn't have enough details for me. I've got plenty of questions to ask to finish my project (I am a researcher and a newbie Ruby and RoR programmer).

funded

Answer rmc's question

People succeed in answering rmc's questions 0% of the time (0 success in 2 attempts).

Counter Offer:

$6 | $7 | $8 | other:

Answers by: Rich Collins | Federico

Rich Collins's Answer:

Reply by Rich Collins 911 days ago

I can probably walk you through it. Chat with me and we can figure it out.

Reply by Rich Collins 911 days ago

script/generate scaffold comment

> a) code underlying a "Create Comment" link, which will be in a list or show view of a model, that will open the create view of the comment model.

<%= link_to 'Comment on this Post', :controller => 'comments', :action => 'new' %>

> b) code underlying the create comment view that will prompt for comment title and comment text, and then save the comments on submit.

The scaffold will take care of this

Reply by rmc 908 days ago

Rich,
Thank you for your reply. Ok, let's work on this baby.

Assume I have a Post model that acts_as_commentable. In the Listing Posts view, for each post record, there is attached (ala scaffold style) an option Comment, whose underlying code is something like:

<%= link_to "comments", :controller => "comment", :action => "list_by_id",
also the record id value as @model_id
aslo the model name as @model_type

The Comments Listing will only list comments associated with the id of the current record of the Post model
The list_by_id action of the comments controller:

def list_by_id
must receive or know about @model_id
must receive or know about @model_type
must select * from comments where commentable_id = @model_id and commentable_type = @model_type
then pass query set to the list_by_id.rhtml
end

For adding new comments, Felipe (creator of acts_as_commentable) has a new posting about this plugin in his website: http://juixe.com/techknow/. He offers the form helper:

_comment_form.rhtml
<% start_form_tag :action => 'add_comment' %>
<%= text_field 'comment', 'title' %>

<%= text_field 'comment', 'comment' %>

<%= submit_tag 'Add Comment' %>

<%= hidden_field 'commentable', 'commentable', :value => @model.type
%>
<%= hidden_field 'commentable', 'commentable_id', :value => @model.id %>

<% end_form_tag %>

and the add_comment action in the comments controller:

def add_comment
commentable_type = params[:commentable][:commentable]
commentable_id = params[:commentable][:commentable_id]
# Get the object that you want to comment
commentable = Comment.find_commentable
(commentable_type, commentable_id)

# Create a comment with the user submitted content
comment = Comment.new(params[:comment])
# Assign this comment to the logged in user
comment.user_id = session[:user].id

# Add the comment
commentable.comments << comment

redirect_to :action => commentable_type.downcase,

:id => commentable_id
end

My new.rhtml for comments is as follows:

New comment

<%= start_form_tag :action => 'add_comment' %>
<%= render :partial => 'comment_form' %>
<%= submit_tag "Create" %>
<%= end_form_tag %>
<%= link_to 'Back', :action => 'list' %>

Now, my question:

When I call the New.rhtml for Comments, how do I pass the current model's (in my example Post) record id, and the model type " Post " to serve as @model_id and @model_type respectively? Define as @ variables somewhere?

About the red-highlighted lines in the add_comment action, I need to:

redirect_to :action => 'list_by_id',

pass the current @model_id and @model_type

Rich, I hope this is clear enough. Email me again if you need clarification.

Thanks much.
rmc
- Show quoted text -

Reply by Rich Collins 908 days ago

Hmm I think it may be easier to approach it this way:

work within the posts controller:

posts/comments/1

Where 1 is the id of the post

Then you can just do this from within the controller:

@post = Post.find(1)

and in the comments.rhtml view:

<% for comment in @post.comments %>
<%= render :partial => 'comment', :locals => {:comment => comment %>
<% end -%>

to add a comment:

<%= form_tag, :action => 'add_comment', :id => @post.id %>
<%= render :partial => 'comment_form' %>
<%= submit_tag 'Submit Comment' %>
<%= end_form_tag %>

in the controller:

def add_comment
@post = Post.find(params[:id])
@post.comments << Comment.new(params[:comment])
flash[:message] = "Comment Added"
redirect_to :action => 'show', :id => @post.id
end

Using this technique, you don't have to worry about the whole commentable_type, commentable_id, the polymorhpic assocation on the posts model will take care of everything for you!

Reply by rmc 907 days ago

Rich,

Don't we need to consider commentable_type? The comments table contains comments on any instance of any model: Post, Task, User, Project, etc. Each comment is uniquely identified with the combination of commentable_type (Post, Task, etc.) and the commentable_id (the id of the Post or Task record).

The add_comment action must be generic. We need to pass to it the commentable_type ("Task" if we are adding a comment to a Task record), and the commentable_id (the id of the record we are commenting on). Check the add_comment code in my previous posting.

My particular problem is: where and how do I get the data to pass to the controller action add_comment and to the partial _comment_form. rhtml, and how do I pass them over?

rmc

Reply by Rich Collins 907 days ago

I see. It would make sense to have one comments/new page then. You just need to set an instance variable for the form to use.

ex.

in routes.rb

map.new_comment('comments/new/:commentable_id/:commentable_type', :controller => 'comments', :action => 'new')

in the comments controller:

def new
@comment = Comment.new(params)
end

in _form.rhtml

... other fields
<%= text_field :comment, :commentable_type %>
<%= text_field :comment, :commentable_id %>

This will allow you to send users to the new comments page with the form pre-seeded to the type of comment it will be. Then, when you submit the form, it should create a new comment with the type and id correctly set.