New B
New B

Reputation: 21

Nested Comments in Rails 4 using gem 'closure_tree'

Nested Comments in Rails 4 using gem 'closure_tree'

Given that comments is a nested resource of articles as such, how do I refactor the following code from the sitepoint tutorial to create nested comments?

In particular, how do I integrate these two lines:

@comment = parent.children.build(comment_params)

@comment = @article.comments.create(comment_params)

http://guides.rubyonrails.org/getting_started.html

routes.rb

resources :articles do
  resources :comments
end

comments_controller.rb

class CommentsController < ApplicationController
  def create
    @article = Article.find(params[:article_id])
    @comment = @article.comments.create(comment_params)
    redirect_to article_path(@article)
  end


  private
    def comment_params
      params.require(:comment).permit(:commenter, :body)
    end
end

http://www.sitepoint.com/nested-comments-rails/

comments_controller.rb

class CommentsController < ApplicationController
  def create
    if params[:comment][:parent_id].to_i > 0
      parent = Comment.find_by_id(params[:comment].delete(:parent_id))
      @comment = parent.children.build(comment_params)
    else
      @comment = Comment.new(comment_params)
    end
  end


  private
      def comment_params
      params.require(:comment).permit(:body)
  end
end

Upvotes: 2

Views: 1634

Answers (2)

Ravk
Ravk

Reputation: 46

Since comment belongs_to article, you should be able to do something similar.

@comment = parent.children.build(comment_params)
@comment.article_id = @article.id #(get the article id)
@comment.save

Upvotes: 0

Richard Peck
Richard Peck

Reputation: 76784

This is not the answer you want, but will help you nonetheless


Nesting

enter image description here

We achieved a truly "nested" commenting display using the ancestry gem (just looked up closure_tree - very nice, will be looking into this more).

I call it "truly" nested, because if you want the nesting to occur for replies as well as just standardized comments, you have to do something special. You have to perform a recursive loop, including all the nested comments you need

To achieve this, you need 3 things:

  1. Hierarchy in your model
  2. Ability to access hierarchies correctly (children / parents etc)
  3. Recursive view to display them all

Here's how we did it:


Hierarchy

The hierarchy in your model is the first, and most important, step. Your closure_tree example seems to demonstrate this very well. We used ancestry -- seems they both achieve the same result in different ways:

enter image description here

As you can see from the data, you'll be able to see that storing the hierarchies of the data gives you the ability to then call them properly (which is crucial for the displaying of them). Ancestry denotes structure by using the following format: parent_1/parent_2 - I believe closure_tree does it somewhat differently

--

Access

Once you have the database set up correctly, you have to then determine the access to the data.

We use Ancestry's children method:

enter image description here

This allows us to cycle through the objects, from which we'll then be able to call the children method:

--

Recursive Loop

Finally, you'll be able to tie all of this together with your view:

#app/views/comments/index.html.erb
<%= render partial: "comment", locals: { collection: @comments } %>

#app/views/comments/_comment.html.erb
<% collection.arrange.each do |comment, sub_item| %>
    <li>
      <%= link_to comment.title, your_path(comment) %>
      <%= render partial: "category", locals: { collection: category.children } if category.has_children? %>
    </li>
<% end %>

This simple partial will give you the recursion required to create truly nested comment structures. Of course, it will depend on your closure_tree gem, but should give you some nice ideas either way!

Upvotes: 3

Related Questions