Antonio Antonio - 8 days ago 7
Ruby Question

Method designed to find a Comment's parent Post will break if a parent comment (comment on a comment) is deleted

I have a method to find the parent post of a child comment. Assuming there is a Post and Comment layout like so:

Post
Comment
Child comment # Find parent post all the way up tree
Child comment
Comment


I have a method in my User model to take the user's comments and put them in a hash along with the parent post that looks like so:

# user.rb
def comment_post_hash
@comment_hash = []
@user_comments = Comment.where(user_id: self.id)
@user_comments.all.each do |co|
post = co.find_parent_post # Another method defined below
@comment_hash.push( { comment: co, post: post} )
end
@comment_hash
end

# comment.rb
def find_parent_post
return self.commentable if self.commentable.is_a?(Post)
self.commentable.find_parent_post
end


The problem is that this method will break if there is a parent comment that is deleted somewhere in the chain like so:

Post
<deleted> # No longer exists
Child comment # This will break the method.
Child comment
Comment


Is there a way to refactor this method so that it could possibly be rescued and be able find the Parent post regardless if the parent comment is deleted? I can only think of adding a a
post_id
to a comment but curious if there were other ways to go about solving this issue.

Answer

I will give you a quick answer, no there is not a way to change the method to look for a deleted items parent because once you have deleted it you have lost that relation.

Several solutions that come to mind are as you suggested using a post_id, which will work fine for your needs (if I remember correctly from your previous question you are currently only allowing comments two levels deep), however If this were to change in the future and you want to allow further levels of comments, this approach wont work to well because you will skip lots of ancestor comments and go straight to the upper post, potentially ruining the comment structure.

If you want to future proof it for this case, one suggestion I would make would be to use the polymorphic relation you already have, and when a comment is deleted, point all children to its parent, and use a seperate column such has has_deleted_parent or something to indicate that there has been a break in the original comment structure and make it easier to protect the structure in the views.

But then this approach also has some problems such as what if the deleted comments parent then gets deleted, then a boolean would not be enough and a counter would be required, but then things start to get more complicated.

Another approach would be to rethink the UX, so once a comment is deleted all its children then get deleted? or an approach I would prefer is not allowing the deletion of comments, and instead allowing the superficial removal of comments, where the actual model still exists, therefore protecting your data, but just as an empty shell, and in the views just some text along the lines of "this comment has been removed"

Not a direct answer I know but I hope its perhaps been a help!

Comments