缩进深度优先搜索的每个子项(ruby on rails)?
Indent every child of a depth first search (ruby on rails)?
我是 rails 的新手,我想知道是否有一种简单(或不简单)的方法来缩进 DPS 的每个子项?
我有一个名为 "Comment" 的模型 has_many :comments 和 belongs_to :comment。在我看来,我已经实现了一个 DPS 来显示每条评论和对该评论的每条评论,以及对该评论的每条评论等。
我的代码如下所示:
<div class=feed>
<% @comments.each do |comment| %>
<% if comment.comment_id == nil # display all original comments %>
<!-- subject -->
<div class="subject">
<%= comment.subject %>:
</div>
<!-- create array of replies -->
<% replies = Array.new %>
<% replies.push(comment) %>
<% while replies.any? %>
<% reply = replies[0] %>
<% replies.delete_at(0) %>
<!--- name -->
<div class="comment">
<%= User.find(reply.user_id).name %>
<!-- comment -->
<%= reply.body %>
<% if user_signed_in? %>
<%= link_to "reply", new_comment_comment_path(reply.id) %>
<% end %>
</div>
<% reply.comments.each do |further_replies| %>
<% replies.push(further_replies) %>
<% end %>
<br>
<% end %>
<br>
<% end %>
<% end %>
</div>
我将每个评论推送到 "replies" 并逐一访问每个回复。
有没有什么好的方法可以缩进每个子评论?
谢谢!
您可以使用 act_as_tree 结构,在这种情况下您的模型将类似于 -
class Comment
has_many :replies, class_name: 'Comment', foreign_key :comment_id
belongs_to :user
end
你的 html 代码在那种情况下会非常简单,比如
<div class=feed>
<% @comments.each do |comment| %>
<div class="subject">
<%= comment.subject %>:
</div>
<% comment.replies.each do |reply| %>
<div class="comment">
<%= reply.user..name %>
<%= reply.body %>
<% if user_signed_in? %>
<%= link_to "reply", new_comment_comment_path(reply.id) %>
<% end %>
</div>
<br>
<% end %>
<br>
<% end %>
</div>
我想出了一个效果很好的不同方法。我在 "CommentsController" 中实现了递归深度优先搜索,它返回了 { comments => amount_to_indent } 的散列,其中评论按访问顺序排列。在视图文件中遍历哈希,在适当的地方使用注释和 amount_of_indent。
class CommentsController < ApplicationController
def index
@comments = Comment.all
# depth first search
@visited = Hash.new
@comments.each do |comment|
if !comment.comment_id # has not parent comment
indent = 0
comment_array = DFS(comment, @visited, indent)
end
end
end
def DFS(comment, visited, indent)
visited[comment] = indent # add elements in order in which they are visited
comment.comments.each do |reply|
DFS(reply, visited, indent + 4)
end
visited
end
并且在视图文件中:
<div class="feed">
<% @visited.each do |reply, indent| %>
<!-- display subject of all parent comments -->
<div class="subject">
<% if !reply.comment_id? %>
<%= reply.subject %>:
<% end %>
</div>
<!--- name and content -->
<div class="comment">
<!-- preceed comment with indent -->
<%= raw((' ') * indent) %>
<%= User.find(reply.user_id).name + ":" + reply.body %>
<% if user_signed_in? %>
<%= link_to "reply", new_comment_comment_path(reply.id) %>
<!--%= link_to 'delete', response, method: :delete, data: { confirm: 'Are you sure?' } %-->
<% end %>
</div>
<% end %>
</div>
如果有人遇到和我一样的问题!
我是 rails 的新手,我想知道是否有一种简单(或不简单)的方法来缩进 DPS 的每个子项?
我有一个名为 "Comment" 的模型 has_many :comments 和 belongs_to :comment。在我看来,我已经实现了一个 DPS 来显示每条评论和对该评论的每条评论,以及对该评论的每条评论等。
我的代码如下所示:
<div class=feed>
<% @comments.each do |comment| %>
<% if comment.comment_id == nil # display all original comments %>
<!-- subject -->
<div class="subject">
<%= comment.subject %>:
</div>
<!-- create array of replies -->
<% replies = Array.new %>
<% replies.push(comment) %>
<% while replies.any? %>
<% reply = replies[0] %>
<% replies.delete_at(0) %>
<!--- name -->
<div class="comment">
<%= User.find(reply.user_id).name %>
<!-- comment -->
<%= reply.body %>
<% if user_signed_in? %>
<%= link_to "reply", new_comment_comment_path(reply.id) %>
<% end %>
</div>
<% reply.comments.each do |further_replies| %>
<% replies.push(further_replies) %>
<% end %>
<br>
<% end %>
<br>
<% end %>
<% end %>
</div>
我将每个评论推送到 "replies" 并逐一访问每个回复。
有没有什么好的方法可以缩进每个子评论?
谢谢!
您可以使用 act_as_tree 结构,在这种情况下您的模型将类似于 -
class Comment
has_many :replies, class_name: 'Comment', foreign_key :comment_id
belongs_to :user
end
你的 html 代码在那种情况下会非常简单,比如
<div class=feed>
<% @comments.each do |comment| %>
<div class="subject">
<%= comment.subject %>:
</div>
<% comment.replies.each do |reply| %>
<div class="comment">
<%= reply.user..name %>
<%= reply.body %>
<% if user_signed_in? %>
<%= link_to "reply", new_comment_comment_path(reply.id) %>
<% end %>
</div>
<br>
<% end %>
<br>
<% end %>
</div>
我想出了一个效果很好的不同方法。我在 "CommentsController" 中实现了递归深度优先搜索,它返回了 { comments => amount_to_indent } 的散列,其中评论按访问顺序排列。在视图文件中遍历哈希,在适当的地方使用注释和 amount_of_indent。
class CommentsController < ApplicationController
def index
@comments = Comment.all
# depth first search
@visited = Hash.new
@comments.each do |comment|
if !comment.comment_id # has not parent comment
indent = 0
comment_array = DFS(comment, @visited, indent)
end
end
end
def DFS(comment, visited, indent)
visited[comment] = indent # add elements in order in which they are visited
comment.comments.each do |reply|
DFS(reply, visited, indent + 4)
end
visited
end
并且在视图文件中:
<div class="feed">
<% @visited.each do |reply, indent| %>
<!-- display subject of all parent comments -->
<div class="subject">
<% if !reply.comment_id? %>
<%= reply.subject %>:
<% end %>
</div>
<!--- name and content -->
<div class="comment">
<!-- preceed comment with indent -->
<%= raw((' ') * indent) %>
<%= User.find(reply.user_id).name + ":" + reply.body %>
<% if user_signed_in? %>
<%= link_to "reply", new_comment_comment_path(reply.id) %>
<!--%= link_to 'delete', response, method: :delete, data: { confirm: 'Are you sure?' } %-->
<% end %>
</div>
<% end %>
</div>
如果有人遇到和我一样的问题!