Как мне заставить метод destroy работать для вложенных ресурсов в Rails? - PullRequest
0 голосов
/ 08 апреля 2020

В настоящее время изучаю Ruby на Rails и создаю простое приложение для блога с комментариями. У меня есть модель Comment и модель Article. Comment - это полиморф c, и обе модели имеют много комментариев.

Я пытаюсь найти метод destroy, который может удалить как комментарии, принадлежащие Comment, так и те которые принадлежат Article (и остаются [удаленными] без уничтожения их детей, как в Reddit, хотя я даже не дошел до этой части).

Я пробовал разные пути, но у меня нет еще не понял Вложенные пути все еще меня немного смущают, и я не уверен, как передать параметры, которые запрашивает путь при создании link_to.

Это мои файлы:

rout.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

показать . 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.

Не могли бы вы дать некоторые рекомендации относительно того, что мне следует делать или что я должен исправить? Я также не уверен, как удалить родительские комментарии, и мне не удалось найти информацию, которая подходит для этого случая. Если вы знаете, куда мне указать, у меня все глаза.

Спасибо.

Ответы [ 2 ]

0 голосов
/ 08 апреля 2020

проверьте тщательно, чтобы уничтожить метод

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

первая проверка @comment = @commentable.comments.find(params[:id]) имеет ли @comment какое-либо значение или нет?

просто добавьте одно условие, подобное этому, и оно не будет выбрасывать ошибка:

@comment.destroy if @comment

, если @comment равен nil, и попытка уничтожить его выдаст ошибку.

0 голосов
/ 08 апреля 2020

Из-за структуры вашей модели дизайна.

Ваше мнение

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

Ваш find_commentable

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

@ commentable будет классом Comment, поэтому он выиграл ' * у вас есть .comments методы в качестве вашей статьи класса

...