如何在rails上的ruby中实现递归删除?

时间:2016-05-24 06:56:49

标签: mysql ruby-on-rails ruby

我在轨道上使用ruby创建应用程序,类似于Reddit,在项目中我决定使用Commentpolymorphic association模型上使用递归。

递归删除文章< - 评论< - 评论等

问题在于,当我删除文章时,哪些评论取决于并使用:delete_all(或:destroy,已经尝试过)has_many关联,它只会删除第一个评论水平 同样的方式发生在Comments,只有第一级回复被删除,我真的不想要孤儿评论。

问题是,如何在此上下文中实现递归删除?

模型/ article.rb:

class Article < ActiveRecord::Base
  belongs_to :user
  has_and_belongs_to_many :tags
  has_many :comments, as: :commentable , :dependent => :delete_all
end

模型/ comment.rb:

class Comment < ActiveRecord::Base
  belongs_to :user
  belongs_to :commentable, polymorphic: true
  has_many :comments, as: :commentable , :dependent => :delete_all
end

articles_controller.rb:

def destroy
    @article = Article.find(params[:id])
    @comments = @article.comments.destroy
    @article.destroy

    redirect_to articles_path
end

comments_controller.rb:

class CommentsController < ApplicationController
before_action :find_commentable
                    .
                    .
                    .
    def create
      @comment = @commentable.comments.new(comment_params)

      if @comment.save
        redirect_to :back, notice: 'Your comment was successfully posted!'
      else
        redirect_to :back, notice: "Your comment wasn't posted!"
      end
    end

    private

    def comment_params
      params.require(:comment).permit(:body, :user_id)
    end

    def find_commentable
      @commentable = Comment.find_by_id(params[:comment_id]) if params[:comment_id]
      @commentable = Article.find_by_id(params[:article_id]) if params[:article_id]
    end
end

视图/物品/ show.html.erb

.
.
.
<ul>
  <%= render(partial: 'comments/comment', collection: @article.comments) %>
</ul>

视图/评论/ _comment.html.erb

<li>
  <%= comment.body %> -
  <small>Submitted <%= time_ago_in_words(comment.created_at) %> ago by <%= User.find(comment.user_id).name %></small>

  <%= form_for [comment, Comment.new] do |f| %>
      <%= f.hidden_field(:user_id , :value => current_user.id) %>
      <%= f.text_area :body, placeholder: "Add a Reply", required: true %><br/>
      <%= f.submit "Reply"  %>
      <% end %>
  <ul>
      <%= render partial: 'comments/comment', collection: comment.comments %>
  </ul>
</li>

1 个答案:

答案 0 :(得分:1)

您需要在评论和文章中使用:destroy代替:delete_all,才能使级联正常删除does not trigger callbacks

另请注意@comments = @article.comments.destroy此处不会执行任何操作(您有一个CollectionProxy,因此它会function like this)而您应该使用destroy_all。但这并不能正确解决您的递归删除问题,并且只会删除顶级注释的注释,并停在那里。实际上,如果您使用:destroy,则根本不需要此行。