Reputation: 21
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
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
Reputation: 76784
This is not the answer you want, but will help you nonetheless
Nesting
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:
- Hierarchy in your model
- Ability to access hierarchies correctly (children / parents etc)
- 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:
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:
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