Nested comments from scratch

后端 未结 9 1255
生来不讨喜
生来不讨喜 2020-12-25 09:03

Let\'s say I have a comment model:

class Comment < ActiveRecord::Base
    has_many :replies, class: \"Comment\", foreign_key: \"reply_id\"
end
         


        
9条回答
  •  佛祖请我去吃肉
    2020-12-25 09:28

    My approach is to make this done as efficient as possible. First lets address how to do that:

    1. DRY solution.
    2. Least Number of queries to retrieve the comments.

    Thinking about that, I have found that most of the people address the first but not the second.So lets start with the easy one. we have to have partial for the comments so referencing the answer of jeanaux

    we can use his approach to display the comments and will update it later in the answer

    
    
    <%= render partial: "comment", collection: @comments %>

    <%= comment.content %>

    <%= render partial: "comment", collection: comment.replies %>

    We must now retrieve those comments in one query if possible so we can just do this in the controller. to be able to do this all comments and replies should have a commentable_id (and type if polymorphic) so that when we query we can get all comments then group them the way we want.

    So if we have a post for example and we want to get all its comments we will say in the controller. @comments = @post.comments.group_by {|c| c.reply_id}

    by this we have comments in one query processed to be displayed directly Now we can do this to display them instead of what we previously did

    All the comments that are not replies are now in the @comments[nil] as they had no reply_id (NB: I don like the @comments[nil] if anyone has any other suggestion please comment or edit)

    
    
    <%= render partial: "comment", collection: @comments[nil] %>

    All the replies for each comment will be in the has under the parent comment id

    
    

    <%= comment.content %>

    <%= render partial: "comment", collection: @comments[comment.id] %>

    To wrap up:

    1. We added an object_id in the comment model to be able to retrieve them( if not already there)
    2. We added grouping by reply_id to retrieve the comments with one query and process them for the view.
    3. We added a partial that recursively displays the comments (as proposed by jeanaux).

提交回复
热议问题