如何使用destroy方法来处理Rails中的嵌套资源



目前正在学习RubyonRails并创建一个带有注释的简单博客应用程序。我有一个Comment模型和一个Article模型。CCD_ 3是多态的,两种模型都有很多评论。

我正在尝试想出一个destroy方法,它能够删除属于Comment的评论和属于Article的评论(并且保持为[已删除],而不会破坏他们的孩子,就像在Reddit中一样,尽管我甚至还没有谈到这一部分(。

我尝试过不同的道路,但还没有走对。嵌套的路径仍然让我有点困惑,我不确定在创建link_to时如何传递路径请求的params。

这些是我的文件:

routes.rb:

Rails.application.routes.draw do
get 'comments/new'
get 'comments/create'
get 'articles/index'
get 'articles/show'
root 'articles#index'
resources :articles  do 
resources :comments
end
resources :comments do 
resources :comments
end

end

article.rb:

class Article < ApplicationRecord
has_many :comments, as: :commentable
end

comment.rb:

class Comment < ApplicationRecord
belongs_to :commentable, polymorphic: :true
has_many :comments, as: :commentable
end

comments_controller.rb:

class CommentsController < ApplicationController
before_action :find_commentable
def new
@comment = Comment.new
end
def create
@comment = @commentable.comments.new(comment_params)
if @comment.save
redirect_back(fallback_location: root_path)
else
redirect_back(fallback_location: root_path)
end
end 
def destroy
@comment = @commentable.comments.find(params[:id])
@comment.destroy
redirect_back(fallback_location: root_path)
end
private
def comment_params
params.require(:comment).permit(:body)
end
def find_commentable
if params[:article_id]
@commentable = Article.find_by_id(params[:article_id])
elsif params[:comment_id]      
@commentable = Comment.find_by_id(params[:comment_id])
end
end
end

show.html.erb,其中属于Article.rb的通信的形式为:

<h1> <%= @article.title %> </h1>
<p> <%= @article.body %> </p>
<small>Submitted <%= time_ago_in_words(@article.created_at) %> ago </small> <br/>
<h3>Comments</h3>
<%= form_for [@article, Comment.new] do |f| %>
<%= f.text_area :body, placeholder: "Say something!" %> <br/>
<%= f.submit "Submit" %>
<% end %>
<ul class="parent-comment">
<%= render partial: 'comments/comment', collection: @article.comments %>
</ul>
<%= link_to "Index", articles_path %>

还有部分_comment.html.erb,它显示了属于文章的评论以及属于其他评论的评论,并且我正在尝试集成link_to:

<p> <%= comment.body %> </p>
<small>Submitted <%= time_ago_in_words(comment.created_at) %> ago </small> <br/>
<%= form_for [comment, Comment.new] do |f| %>
<%= f.text_area :body, placeholder: "Add a reply!" %><br/>
<%= f.submit "Reply" %>
<%= link_to "Delete", comment_path(comment), method: :delete %>
<% end %>
<ul>
<%= render partial: 'comments/comment', collection: comment.comments %>
</ul>

每当我似乎找到了正确的道路时,就会出现NoMethodError in CommentsController#destroy — undefined method `comments' for nil:NilClass。为什么控制器会显示为未定义?据我所见,它在new方法中起作用。

你能给我一些指导,告诉我应该做什么或应该解决什么吗?我也不知道如何删除家长的评论,我也没有找到适合这种情况的信息。如果你知道该把我指向哪里,我会全神贯注。

谢谢。

因为您的设计模型结构。

您的视图

<%= link_to "Delete", comment_path(comment), method: :delete %>

您的发现_可注释

elsif params[:comment_id]      
@commentable = Comment.find_by_id(params[:comment_id])
end

@commentable将是一个Comment类,因此它不会有.comments方法作为文章

仔细检查以销毁方法

def destroy
@comment = @commentable.comments.find(params[:id])
@comment.destroy
redirect_back(fallback_location: root_path)
end

使用@comment = @commentable.comments.find_by(id: params[:id])并检查@comment是否有一些值?

只要添加一个这样的条件,它就不会抛出错误:

@comment.destroy if @comment

如果CCD_ 16是CCD_。

最新更新