I've been having problems making threaded comments for the last few days. Mainly with creating children and displaying the children. Currently, I have comments shown at the bottom of my articles show view. The top level comments work, but I do not really know how to implement a way for users to "reply" to the top level comments and take them to a form (the comment 'new' view) to create a new comment. I want the controller to determine if the user is creating the new comment in an article or in a comment and create the new comment as a child if its parent is a comment. I've been facing multiple problems, maybe the recursion messes up and I get an infinite loop.
Here is the articles show controller: def show @article = Article.find(params[:id]) @commentable = Article.find(params[:id]) @comments = @commentable.comments # @comments = @commentable.comments.paginate(:page => params[:page]) @comment = Comment.new @title = @article.title end
Here is my comments controller: def show @commentable = find_commentable @comment = @commentable.comments.find(params[:id]) # @comments = @commentable.comments.paginate(:page => params[:page]) end
def new @commentable = find_commentable @comment = Comment.new end
def create @commentable = find_commentable if @comment.commentable_type == "Comment" @comment = @commentable.children.create(param[:comment]) else @comment = @commentable.comments.build(params[:comment]) end @comment.user_id = current_user.id if @comment.save flash[:success] = "Comment saved." redirect_to @commentable else flash[:error] = "Error in creating comment." # @comments = @commentable.comments.paginate(:page => params[:page]) render 'new' end end
Here is the comment creation form: <%= 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 the loop that goes through all of the existing comments: <% unless @comments.nil? || @comments.empty? %> <%= render :partial => 'comments/comment', :collection => @comments %> <%#= will_paginate @comments %> <% end %>
Here is what each individual comment looks like: <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 /><br /> <%= render :partial => 'comments/comment', :collection => @comment.children %> </div>
When I click reply, I get taken to: http://localhost:3000/articles/299/comments and not http://localhost:3000/articles/299/comments/new. I went into rails console and gave one of my comments a comment child, and the recursive nature of the threaded comments gave me recursion that crashed my site.