Rails Ancestry. How can I display a single comment with all its descendants?

125 views Asked by At

helpers/comments_helpers.rb

def nested_comments(comments)
    comments.map do |comment, sub_comments|
      render(comment) + content_tag(:div, nested_comments(sub_comments), :class => 'nested_comments')
    end.join.html_safe
  end

def nested_comment(one_comment)
    one_comment.instance_eval do |comment, sub_comments|
      render(comment) + content_tag(:div, nested_comments(sub_comments), :class => 'nested_comments')
    end.join.html_safe
  end

controllers/comments_controller.rb

 def show
     @comment = Comment.find(params[:id])
 end

views/comments/show.html.erb

...
<%= nested_comment(@comment) %>
...

I keep getting this error and I don't know why: undefined method `render' for #

If I remove the render part of the method, I get another error for content_tag

Can someone tell me how to fix these errors?

Comments Schema(From comments section below)

create_table "comments", force: :cascade do |t| 
  t.text "content" 
  t.datetime "created_at", null: false 
  t.datetime "updated_at", null: false 
  t.string "ancestry" 
end
1

There are 1 answers

3
engineersmnky On

Does this work? I am taking a stab in the dark because Comment is not very clearly defined.

I have never used ancestry before but here is a wild guess on implementation based on the documentation:

def nest_comments(*comments)
    comments.map do |comment|
      comment_block = render(comment) 
      comment_block += content_tag(:div, 
                                   nested_comments(*comment.children), 
                                   :class => 'nested_comments') if comment.has_children?
      comment_block
    end.join.html_safe
end

This will recursively run through all the comments and sub comments (beware of the extreme n+1 issues here because if sub_comments executes a new query recursively it could create performance impacts very quickly.

You should be able to call like

<%= nest_comments(@comment) %>

or

@comments = Comment.all
<%= nest_comments(*@comments.to_a) %>

The second one may have increasing performance impacts if the comments are not top level and they are called recursively multiple times but without a better understanding this question is hard to answer.