线程多态注释

时间:2014-02-28 13:11:02

标签: ruby-on-rails ruby ruby-on-rails-4

我已经设置了两个可通过相同注释表评论的模型:

我的评论架构:

  create_table "comments", force: true do |t|
    t.text     "body"
    t.integer  "commentable_id"
    t.string   "commentable_type"
    t.integer  "user_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

我的评论模型:

class Comment < ActiveRecord::Base
  belongs_to :commentable, polymorphic: true
  belongs_to :user
  acts_as_votable
end

我的电影模特

class Movie < ActiveRecord::Base
  belongs_to :user
  has_many :comments, as: :commentable
end

我的书模型:

class Book < ActiveRecord::Base
  belongs_to :user
  has_many :comments, as: :commentable
end

我的评论控制器:

def index
  @commentable = find_commentable
  @comments = @commentable.comments
end

def create
  @commentable = find_commentable
  @comment = @commentable.comments.build(params[:comment])
  @comment.user = current_user
  if @comment.save
    flash[:notice] = "Successfully created comment."
    redirect_to @commentable
  else
    render :action => 'new'
  end
end

  def upvote_movie
  @movie = Movie.find(params[:movie_id])
  @comment = @movie.comments.find(params[:id])
  @comment.liked_by current_user

  respond_to do |format|
    format.html {redirect_to :back}
  end
end


  def upvote_book
  @book = Book.find(params[:book_id])
  @comment = @book.comments.find(params[:id])
  @comment.liked_by current_user

  respond_to do |format|
    format.html {redirect_to :back}
  end
end


private

def find_commentable
  params[:commentable_type].constantize.find(params[:commentable_id])
end
end

如何将线程(回复评论)添加到我已有的内容?

这是一篇关于线程的博客:http://www.davychiu.com/blog/threaded-comments-in-ruby-on-rails.html

我只是不确定如何把两者放在一起。

以下是我在电影节目视图中的内容:

<%= render partial: "comments/form", locals: { commentable: @movie } %>


<% @comments.each do |comment| %>

<hr>
  <p>
   <strong><%= link_to comment.user.username, user_path(comment.user), :class => "user" %>
</strong> <a><%= "(#{time_ago_in_words(comment.created_at)} ago)" %></a>
  </p>

  <p>

    <%= simple_format(auto_link(comment.body, :html => { :target => '_blank' } )) %>
<% end %>

以下是我的评论表格:

<%= form_for [commentable, Comment.new] do |f| %>
  <%= hidden_field_tag :commentable_type, commentable.class.to_s %>
  <%= hidden_field_tag :commentable_id, commentable.id %>
  <p>
    <%= f.text_area :body %>
  </p>
  <p><%= f.submit "Submit" %></p>
<% end %>

2 个答案:

答案 0 :(得分:1)

我扫描了你提到的文章,发现解决方案非常有限。

本文的基本思想是将评论本身设置为可评论。因此,嵌套注释实际上不是帖子的评论,而是父评论的评论。

缺点显而易见且不可接受:

  1. 很难让其他事情正确。例如,posts.comments.size不再是正确的。

  2. 您将严格依赖此结构。如果在某一天你不想在线上显示评论,但显而易见,你......会踢出一块石头。

  3. 如果您想在当前的评论系统上进行,那很难。

  4. 实际上,一个简单的解决方案可以解决问题:

    1. 在评论模型中添加额外的字段reply_to,引用其他评论的ID。

    2. 添加评论时,如果回复一个,请添加reply_to ID。

    3. 显示时,显示reply_to null的所有评论列表。

    4. 然后,对于每个评论,显示嵌套的评论都有其ID。并递归地做。

    5. 如果要限制嵌套级别,可以添加额外的nested_level字段,从前端进入。如果嵌套限制为3,则不允许任何注释回复嵌套级别为3的注释。

    6. 添加:演示助手以递归方式呈现

      def render_replied_comments(comment)
        if comment.has_reply
          comments.replies.each do |reply|
            render partial: 'comment', locals: {comment: reply}
            render_replied_comment(reply)
          end
        end
      end
      
      # View
      @post.top_level_comments.each do |comment|
        render partial: 'comment', locals: {comment: comment}
      end
      

答案 1 :(得分:0)

您可以将parent_id添加到作为自引用关系的评论模型中。所以父注释的parent_id为nil,所有子注释都有父注释的parent_id。你实际上是在构建一棵树。

Ancestory Gem非常适合这种情况,也可以提供良好的学习体验。