2016-05-24 13 views
2

Redditと同様のRubyでアプリを作っていますが、を使ってCommentモデルで再帰を使うことにしました。Rubyでレール上で再帰的な削除を実装する方法は?

再帰削除条<から<コメント - コメントなど

問題については、私は依存し:delete_all使ってコメント条、削除するときhas_many関連に(または:destroyを、すでにことを試してみました)ということで、それをコメントの最初のレベルのみが削除されます。
同じように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

記事やコメントを削除するコードを共有できますか? – Anand

答えて

1

:delete_allの代わりに:destroyを使用する必要がありますカスケーディングのためのコメントと記事の両方が削除does not trigger callbacksとして正しく動作するようにしてください。

@comments = @article.comments.destroyは(あなたがCollectionProxyので、それはfunction like this意志を持っている)、ここで何もしませんし、あなたが代わりにdestroy_allを使用する必要があります注意してください。これだけでは再帰的な削除問題は適切に解消されず、トップレベルのコメントのコメントのみが削除され、そこで停止します。実際には、:destroyを使用する場合は、この行はまったく必要ありません。

+1

私は家に帰るとすぐにお試しになります。 –

+0

お待ちください。私は時間がなかった、仕事はmeanyされています。 あなたが言ったように私はそれを行うことができました:has_many関連と:dependent =>:多型の両方の上で破棄します。おかげさまで –

関連する問題