views:

70

answers:

1

Hello, my website has the ability for users to post top level comments successfully, but I am having much trouble with comment children. I am using polymorphic associations, so the comment model can apply to Articles, Profiles, and Pictures. In each of the three cases, the comment will see the model as "commentable".

I want to create a reply link next to each individual comment which passes in the "id" of that particular comment into the comments "new" view page. Then I want the comments "create" method to use that id, @top_level_comment = Comment.find(id), and make a new child using the parameters that the user specified in the "new" comment view, @top_level_comment.children.create(params[:comment]), but I do not know how to put it into code.

So, the user will start on an article show page, which has the following controller:

  def show
    @article = Article.find(params[:id])
    @commentable = Article.find(params[:id])
    @comments = @commentable.comments
    @comment = Comment.new
    @title = @article.title
  end

Then, he will scroll down to the comments on the bottom, and see that there is a reply link via the article show page:

<div id="comment <%= comment.id %>">
  <%= comment.title %>
  | <%= link_to "Permalink", polymorphic_path([@commentable, comment]), :action => :show %>
  | <%= link_to "Reply", polymorphic_path([@commentable, @comment]), :action => :new %>
  | <%= link_to "Edit Comment", polymorphic_path([@commentable, comment]), :action => :edit %>
  | <%= link_to 'Delete Comment', [[@commentable, comment]], :confirm => "Are you sure?", :method => :delete %><br />
  <%= comment.content %><br />
  <%= comment.user.name %><br />
  <%= @comment.children.count %><br /><br />
  <%= render :partial => 'shared/comment', :collection => @comment.children %>

</div>

It is this line in particular where I am having problems:

| <%= link_to "Reply", polymorphic_path([@commentable, @comment]), :action => :new %>

How do I change this to do what I want to do from the description at the top of this post? The polymorphic path does not work. I think it does not work because commentable only works with Articles, Profiles, and Pictures, but not comments. How do I change the path, so it goes to the comments "new" page while passing on the id of the current comment(comment.id)?

Also, my form for adding new comments looks like this:

<%= form_for([@commentable, @comment]) do |f| %>
  <%#= render 'shared/error_messages', :object => f.object %>
  <div class="field">
    <%= f.label :title %><br />
    <%= f.text_field :title %>
  </div>
  <div class="field">
    <%= f.label :content %><br />
    <%= f.text_area :content %>
  </div>
  <div class="actions">
    <%= f.submit "Post Comment" %>
  </div>
<% end %>

Here is what the routing looks like:

  resources :articles do
    resources :comments
  end

Hello, when I follow mark's routing, I get this when I try to view an article:

No route matches {:controller=>"comments", :action=>"create", :article_id=>#<Article id: 300, title: "Filler Title", content: "Sunt sit est incidunt et.", user_id: 6, created_at: "2010-09-08 17:42:10", updated_at: "2010-09-08 17:42:10">}

Added the following new info on September 16, 3:48 PST:

Here's the form that allows the user to comment on a commentable, but it does not work when the @commentable is a comment.

1: <%= form_for([@commentable, @comment]) do |f| %>
2:   <%#= render 'shared/error_messages', :object => f.object %>
3:   <div class="field">
4:     <%= f.label :title %><br />

comments controller "new"

  def new
    @commentable = find_commentable
    @comment = Comment.new
  end

When replying to a comment, it goes to the above, but it does not know what @commentable is, so its value is nil when replying to a comment. How do I make it so that @commentable is the @comment from which the user pressed reply from? Here is the link that allows the user to reply to a comment:

  | <%= link_to "Reply", new_comment_path(comment.children.new) %>

Thank you very much.

A: 

Surely if you're using polymorphic relationship commentable with comments you should define a self referential polymorphic relationship between comment and comments ie. a comment has many comments as commentable.

Then this:

<%= link_to "Reply", [@comment, @comment.comments.new] %>

#routes.rb

map.resources :comments, :articles, :profiles, :pictures do |commentable|
  commentable.resources :comments, :only => [:new, :create]
end
mark
Hello, when I use the following: <%= link_to "Reply", polymorphic_path([comment, comment.children.new]), :action => :new %>Then I get this error: undefined method `comment_comments_path' for #<#<Class:0xb1ba480>:0xb1b9134>. I have posted my routes.rb in the main topic.
Kelp
Hi. You'll need to set up the route. I'll edit my answer ^ Also remove the action => :new as in my example. :)
mark
Hello, I added the routes (minus the map parts, I am using Rails 3), and I get an error that I will add to the main post.
Kelp
Do you have a comments controller? Can you run rake routes without error and see the route /articles/:article_id/comments/new
mark
Hello, I do get an error when I run rake routes. I will post it in the main topic. Yes, I have a comments controller.
Kelp
Hmm. Run rails -v from console and check you're using 3.0 . Or, does your routes.rb file have an initializer something like - ActionController::Routing::Routes.draw do |map| (not sure about this in rails 3.0 haven't looked at it yet).
mark
Yup, I get Rails 3.0.0.rc when I type that. Nope, I do not see an initializer :(
Kelp
I've not tried rails 3 yet but you should according to http://apidock.com/rails/ActionController/Routing.
mark
Here is what my routes.db looks like right now: http://gist.github.com/582995. Do you recommend that I make a new question concerning the routes, then followup on my threaded comments?
Kelp
For the time being I would just troubleshoot the routes.rb file by deleting everything then putting it back little at a time while seeing if "rake routes" works. The chances are you've left some block open or some other simple syntactical error.
mark
Hmm, I am commenting out routes, and the following route is giving me problems :map.resources :comments, :articles, :profiles, :pictures do |commentable| commentable.resources :comments, :only => [:new, :create]end, I do not know why. I tried it without the block, and did each individually, but it does not work either.
Kelp
I thought with rails 3.0 you didn't need the map and it was just resources :articles. Actually you posted that above. Try first removing the leading colon ie. :map should be map.
mark
Oops, I meant to say this ----> resources :comments, :articles, :profiles do |commentable| commentable.resources :comments, :only => [:new, :create] end ---------- It does not seem to be working.
Kelp
Looking at the api in 3.0 you don't need either to pass the block. ie resources :comments, :articles, :profiles do resources :comments, :only => [:new, :create] end http://guides.rubyonrails.org/routing.html#nested-resources
mark
That fixed the routes. How should I go about allowing the user to reply to a comment (threaded comment). | <%= link_to "Reply", polymorphic_path([comment, comment.children.new]), :action => :new %> is the code I have now, but I run into a routing problem (No route matches "/comments/15/comments")
Kelp
To solve the above problem, I did this: | <%= link_to "Reply", new_comment_path(comment.children.new) %>, but after a user clicks on that reply button, it goes to the form, and now I am having trouble with the form because it uses @commentable (the form for posting comments is in the main question at the top). I am having trouble fashioning the create and new methods for the comments controller, so they know that the commentable is actually a comment. I put the new method of my comments controller in the main question. I do not know how to make it so the new method can find out the comment.
Kelp
I have found a way to get this working. Thank you for all your help!
Kelp