简体   繁体   English

在rails上的ruby中嵌套注释和回复

[英]Nested comments and replies in ruby on rails

I am working on my first project in ruby on rails and need to implement comments and replies functionality on it. 我正在研究我在ruby on rails上的第一个项目,需要在其上实现注释和回复功能。 I am facing of displaying replies under each comment as well as if any reply has child replies they need to display under it. 我面临着在每条评论下显示回复以及是否有任何回复都需要在其下显示的子回复。 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 reply. 我只有一个表用于这些所有注释与父键作为回复。 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 reply for first comment and id 3 comment is treated as reply on first reply of first comment. 第二条评论被视为第一条评论的回复,而第3条评论被视为第一条评论第一次回复时的回复。 kindly help regarding to this nested structure that how i can manage it in a best way. 请帮助我了解如何以最佳方式管理它的嵌套结构。 Comment table also has association with 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.. 关于它还有一个RailsCast ..

在此输入图像描述

The term you're looking for is recursion - self replicating. 你正在寻找的术语是递归 - 自我复制。


Use acts_as_tree : You can do this with has_many / belongs_to 使用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. 使用render comment.replies递归 - 它将继续遍历replies直到不再有。 Although this will take some DB processing to do, it will display the comments with nesting. 虽然这需要进行一些DB处理,但它会显示带有嵌套的注释。

-- -

If you wanted to add a reply etc, you just have to populate the "parent" ID: 如果您想添加回复等,则只需填写“父”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: 以上将提交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

This is a rough outline of one approach to this (some elements may be missing, there may well be better ways and there may be glaring errors but hopefully this could be useful): 这是对此的一种方法的粗略概述(某些元素可能缺失,可能有更好的方法,可能存在明显的错误,但希望这可能有用):

=> Comment has_many :replies, dependent: :destroy =>评论has_many :replies, dependent: :destroy

=> A comment will also need to accepts_nested_attributes_for :replies =>评论还需要accepts_nested_attributes_for :replies

=> Reply belongs_to :comment =>回复belongs_to :comment

=> Both will obviously need to belongs_to :user =>两者显然都需要belongs_to :user

=> A Comment will need to belong_to a post/article etc. =>评论需要belong_to于帖子/文章等。


In Routes.rb you may want to nest replies within comments 在Routes.rb中,您可能希望在注释中嵌套回复

resources :comments do
  resources :replies
end

How you integrate these with your post/article model is another question. 如何将这些与帖子/文章模型集成是另一个问题。


We'll need a CommentsController 我们需要一个CommentsController

class CommentsController < ApplicationController
  def index
   @users = User.all
   @inquiries = Inquiry.all
  end

  def new
    @user = User.find_by(id: params[:user])
    @post = Post.find_by(id: params[:post])

    @comment = @post.inquiries.new
    @message = @comment.replies.build
  end

  def create
    @user = User.find_by(id: params[:user_id])
    @post = Post.find_by(id: params[:post_id])

    @comment = Comment.create!(comment_params) #define these below
    @comment.user << @user
    redirect_to #somewhere
 end

And a replies controller: 并回复控制器:

class RepliesController < ApplicationController
  before_action do
    @comment = Comment.find(params[:comment_id])
  end

  def index
    @replies = @comment.replies
    @reply = @comment.replies.new
  end

  def new
    @reply = @comment.replies.new
  end

  def create
    @reply = @comment.replies.new(reply_params)
    #redirect somewhere
  end

You can then build some views based on the above. 然后,您可以基于上述内容构建一些视图。 I should add that the closure_tree gem does seem like a useful one to look at for this. 我应该补充说, closure_tree gem看起来似乎是一个很有用的东西。 Having used the Mailboxer gem previously I would not recommend that though - as customising it is not always straightforwards. 之前我曾经使用过Mailboxer gem,但我不建议这样做 - 因为定制它并不总是直截了当。

I don't necessarily want to only suggest a gem, since you've said that you've already done your homework there, but I've used the mailboxer gem, ( https://github.com/mailboxer/mailboxer ), before for the same sort of use case to good effect. 我不一定只想建议一个宝石,因为你已经说过你已经完成了你的作业,但我已经使用了邮箱宝石,( https://github.com/mailboxer/mailboxer ),之前对于同类用例效果良好。 Admittedly, I had to hack it a little bit to handle some edge cases, but I think in your particular scenario, it would handle things just fine. 不可否认,我不得不破解它以处理一些边缘情况,但我认为在您的特定情况下,它会处理好的事情。 Perhaps more to the point, even if you have to make some changes, that's probably better than rolling your own from scratch. 也许更重要的是,即使你必须做出一些改变,这可能比从头开始自己滚动更好。

With that said, the data structure you've described is enough, in it's essentials to do what you're asking for. 话虽如此,你所描述的数据结构已经足够了,这是你要求做的事情的基本要素。 The final step would just be to set up the association on your Rails model: 最后一步只是在您的Rails模型上设置关联:

class Comment < ActiveRecord::Base
  has_one :parent, class: 'Comment'
end

With that set up, you just need to make sure your views display your threading properly. 通过该设置,您只需确保您的视图正确显示您的线程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM