Creating a Nested Comment thread
A massive part of Reddit is the 'forum' aspect of it, comments and replies, threads of conversations. In this post I will be attempting to make nested comments associated with my posts.
For this, I thought of two options, either running a migration to create a new field in the Post table holding all comments, but I thought it would quickly get messy, especially with replies. A more suitable alternative is to create a Comment table, which holds 3 important details
- user_id (the creator of the comment)
- post_id (the post on which the comment is posted)
- parent_id->nullable() (the id of the comment they are replying too (for replies only, hence nullable))
This solution allows for endless replies, in a more clean and efficient manner. The migration looks a bit like this:
40,000 characters for a body seems a lot, but that is supposedly Reddits comment character limit, so i'll stick with it.
in the blade file for a post we can now add an addition of a comment box by including @_snippets.comment-form
Which under the hood looks like this is just a post request form containing the body of the comment, the post id and the subweddit id. All the user is concerned with is the body of the reply, the rest is given to the post request through hidden form elements such as the post and comment id's.
once this is successful and we have successfully uploaded a comment, we can loop through them iteratively to display them.
@foreach($comments as $comment)
[blade formatting]
@endforeach
To reply to a comment, the process is much the same, we add a 'reply' box in our @_snippets.comments-replies with the same post form, but now attaching the parent_id as the comment being relied to.
From here, I ran in to an issue. I could upload a reply, and the parent_id field was functioning correctly, so next it came time to displaying replies. The code for displaying a comment and a reply has massive overlap, so I thought I could just loop through the comments replies by calling @include(_comments-replies) - supplying the details of the reply.
The issue then would be that the original loop is displaying EVERY comment, replies and all. so, replies would be shown proceeding a comment, but are also shown at the bottom. I attempted to filter out these stray comments by including an if statement at the top of the blade snippet (if parent_id = null then continue) which removed the stay comments, BUT when it came to calling the comments replies, none would display, because obviously they DO contain a parent_id.
I settled on just creating two blade snippets with near the exact same code..
- _comments (includes if parent_id = null)
- _replies (excludes if parent_id = null)]
Which worked. But after letting it sit for a short while, I found this to be something I couldn't settle with. Maybe the issue could be solved in the blade - but I decided to do some refining in the postcontroller@show method. All comments are passed in by this piece of code here
But does it really need the replies if they are being called blade anyway? I thought not. So, instead, the only thing passed to the blade are comments without parent_id's. like so:
This way, the comments looped through in the blade are only primary comments, and the primary comments themselves call their own replies.
To finish off comments, there must be a way to at least remove them, ideally comments could be edited, but for comments to be edited within the blade I would need to use some sort of javascript, which I was not willing to venture in to for the moment, but deleting a comment only requires a simple 'x' in the corner.. suitable enough.
This was my solution - a delete request masked as an icon - identical to the subweddit delete button.
And voila, working comments thread!
It was at this point I researched in to creating likes. I concluded It would require a Likes table, similar to Comments, with the user_id, and the thing being liked. For liking one entity, the relationships seemed simple enough.Though the relationships for liking two entities is where things get tricky, the likes table would have to have a polymorphic relationship with both Post, and Comments so that both are 'likeable', something I deemed beyond the scope of this application, but not impossible.
Comments
Post a Comment