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

Muh*_*zam 4 ruby nested ruby-on-rails

我正在研究我在ruby on rails上的第一个项目,需要在其上实现注释和回复功能.我面临着在每条评论下显示回复以及是否有任何回复都需要在其下显示的子回复.结构将如何如下.

first comment
       Reply to first comment
            reply to first comment first reply
       reply to first  comment
Second comment
      Reply to second comment
Run Code Online (Sandbox Code Playgroud)

这个嵌套结构继续.我只有一个表用于这些所有注释与父键作为回复.表结构如下

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
Run Code Online (Sandbox Code Playgroud)

第二条评论被视为第一条评论的回复,而第3条评论被视为第一条评论第一次回复时的回复.请帮助我了解如何以最佳方式管理它的嵌套结构.注释表还与项目表和用户表关联.建议没有宝石的最佳方式,因为我已经尝试了很多但是它们的深度水平有限.

Ric*_*eck 12

我们以前做过这个.关于它还有一个RailsCast ..

在此输入图像描述

你正在寻找的术语是递归 - 自我复制.


使用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
Run Code Online (Sandbox Code Playgroud)

这将允许以下内容:

#app/views/projects/show.html.erb
<%= render @project.comments %>

#app/views/comments/_comment.html.erb
<%= comment.body %>
<%= render comment.replies if comment.replies.any? %>
Run Code Online (Sandbox Code Playgroud)

递归发生render comment.replies- 它将继续循环replies直到没有更多.虽然这需要进行一些DB处理,但它会显示带有嵌套的注释.

-

如果您想添加回复等,则只需填写"父"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 %>
Run Code Online (Sandbox Code Playgroud)

以上将提交给comments#create行动:

#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
Run Code Online (Sandbox Code Playgroud)


小智 0

我不一定只想建议一个 gem,因为你已经说过你已经在那里完成了你的作业,但我已经使用了邮箱程序 gem,(https://github.com/mailboxer/mailboxer),之前对于同类用例效果良好。诚然,我必须对它进行一些修改才能处理一些边缘情况,但我认为在您的特定场景中,它可以很好地处理事情。也许更重要的是,即使您必须做出一些更改,这也可能比从头开始自己进行更改要好。

话虽如此,您所描述的数据结构就足够了,因为它是完成您所要求的任务的基础。最后一步就是在 Rails 模型上设置关联:

class Comment < ActiveRecord::Base
  has_one :parent, class: 'Comment'
end
Run Code Online (Sandbox Code Playgroud)

设置完毕后,您只需确保视图正确显示线程即可。