0

我是 Rails 新手,我想知道是否有一种简单(或不简单)的方法来缩进 DPS 的每个子项?

我有一个名为“Comment”的模型,它有_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>

我将每条评论推送到“回复”上,并逐条访问每条回复。

有没有缩进每个孩子评论的好方法?

谢谢!

4

2 回答 2

0

I figured out a different approach that worked well. I implemented a recursive depth first search in "CommentsController" that returned a hash of { comments => amount_to_indent }, where comments are in the order that they were visited. In the view file iterated though the hash, using comment and amount_of_indent where appropriate.

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

And in the view file:

<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(('&nbsp') * 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>

If anyone runs into the same issue I did!

于 2015-08-24T03:19:46.870 回答
0

您可以使用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>
于 2015-08-21T18:04:02.213 回答