I am working on my first project in ruby on rails and need to implement comments and replies functionality on it. I am facing of displaying replies under each comment as well as if any reply has child replies they need to display under it. The structure will be some how as follow.
first comment
Reply to first comment
reply to first comment first reply
reply to first comment
Second comment
Reply to second comment
and this nested structure continues. I have only one table for these all comments with parent key to treat as a reply. The table structure is as follow
Id | Comment_body | parent_id | user_id | project_id
1 comment 2 2
2 comment/reply 1 2 2
3 comment/reply 2 2 2
this second comment is treated as a reply to the first comment and id 3 comment is treated as a reply to the first reply of the first comment. kindly help regarding this nested structure that how I can manage it in the best way. The comment table also has an association with the project table and user table. suggest the best way without gem as I already tried many of them but they are limited in-depth level.
We've done this before. There's also a RailsCast about it..
The term you're looking for is recursion - self replicating.
Use You can do this with acts_as_tree
:has_many / belongs_to
#app/models/comment.rb
class Comment < ActiveRecord::Base
belongs_to :project
belongs_to :parent, class_name: "Comment" #-> requires "parent_id" column
has_many :replies, class_name: "Comment", foreign_key: :parent_id, dependent: :destroy
end
This will allow the following:
#app/views/projects/show.html.erb
<%= render @project.comments %>
#app/views/comments/_comment.html.erb
<%= comment.body %>
<%= render comment.replies if comment.replies.any? %>
The recursion occurs with render comment.replies
-- it will continue to loop through the replies
until there are no more. Although this will take some DB processing to do, it will display the comments with nesting.
--
If you wanted to add a reply etc, you just have to populate the "parent" ID:
#config/routes.rb
resources :projects do
resources :comments #-> url.com/projects/:project_id/comments/:id
end
end
#app/views/comments/_comment.html.erb
<%= form_for [comment.project, comment.new] do |f| %>
<%= f.hidden_field :parent_id, comment.parent.id %>
<%= f.text_field :body %>
<%= f.submit %>
<% end %>
The above will submit to the comments#create
action:
#app/controllers/comments_controller.rb
class CommentsController < ApplicationController
def create
@project = Project.find params[:project_id]
@comment = @project.comments.new comment_params
end
private
def comment_params
params.require(:comment).permit(:parent_id, :body)
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With