質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

3回答

1835閲覧

コメント投稿を削除しようとすると`destroy' for nil:NilClassとエラーが出るので解決をお願いします。

KURUMAEBI

総合スコア2

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2020/08/29 09:52

編集2020/08/29 16:27

コメント投稿機能に削除機能を追加したのですが、`destroy' for nil:NilClassと出てしまいます。
この場合コントローラーのdestroyアクションが(blog_id: params[nill]) = nillになるという解釈で合っていますでしょうか?
その場合、params[]内に何のidを代入すればよろしいでしょうか?
解決をお願いします。

### /controller/blog_comments_controller.rb class Public::BlogCommentsController < ApplicationController def create blog = Blog.find(params[:blog_id]) comment = current_user.blog_comments.new(blog_comment_params) comment.blog_id = blog.id comment.save redirect_to public_blog_path(blog) end def destroy BlogComment.find_by(id: params[:id], blog_id: params[:blog.id]).destroy redirect_to public_blog_path(blog) end private def blog_comment_params params.require(:blog_comment).permit(:comment) end end
### blogs_controller.rb class Public::BlogsController < ApplicationController before_action :authenticate_user!, except: [:index] def index @blogs = Blog.search(params[:search]) @blog = Blog.new end def create @blog = Blog.new(blog_params) @blogs = Blog.all @blog.user_id = current_user.id if @blog.save! redirect_to public_blogs_path(@blog), notice: 'Create succsessfuly' else render :create end end def show @blog = Blog.find(params[:id]) @blog_comments = @blog.blog_comments @blog_comment = current_user.blog_comments.new end def edit @blog = Blog.find(params[:id]) if @blog.user != current_user redirect_to public_blogs_path, alert: 'Invalid Access' end end def update @blog = Blog.find(params[:id]) if @blog.update!(blog_params) redirect_to public_blogs_path(@blog.id), notice: 'Update succsessfuly' else render :edit end end def destroy blog = Blog.find(params[:id]) blog.destroy redirect_to public_blogs_path, notice: 'Deleted succsessfuly' end private def blog_params params.require(:blog).permit(:title, :body, :blog_image_id) end end
### /public/blogs/show.html.erb <% @blog.blog_comments.each do |blog_comment| %> <li class="comment"> <div class="card"> <div class="card-body"> <div class="col-3"> <div class="comment-avatar"> <div class="avatar"> <%= attachment_image_tag @user, :profile_image, fallback: "no_image.jpg", :size =>'50x50' %> </div> </div> </div> <div class="comment-entry"><%= blog_comment.comment %></div> <div class="card-footer"> <%= link_to public_user_path(blog_comment.user) do %> <%= blog_comment.user.username %> <% end %> <%= blog_comment.created_at.strftime('%Y/%m/%d') %> <% if blog_comment.user == current_user %> <div> <%= link_to "削除", public_blog_blog_comment_path(blog_comment), method: :delete, class: "btn btn-danger pull-right" %> </div> <% end %> </div> </div> </div> </div> </li> <% end %>
### /migrate/create_blog_comments.rb class CreateBlogComments < ActiveRecord::Migration[5.2] def change create_table :blog_comments do |t| t.text :comment t.integer :user_id t.integer :blog_id t.timestamps t.timestamps end end end

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

自己解決

回答してくださった方々を参考に自分で試行錯誤したら解決できました。
原因はshow.htmlのdestroyパスの()内に与えるidを一つしか指定していなかったことが原因でした。
よって、show.htmlのdestroyパスの()内に新たに:blog_idと同じ値(blog_comment.blog_id)を記述してあげることで投稿したコメントを削除することができました。
私の場合、投稿したブログの中にコメントが複数ある状態を実装するにあたって、ある一つのコメントを指定して上げたとこまではよかったのですが、どのブログの投稿かが不明な状態で削除しようとしたため`destroy' for nil:NilClassと怒られたのだと思います。
今回の件で、最終的に直した点はshow.html(view側)とその処理後のリダイレクト先なのでページ上、ターミナル上でコントローラを指すエラーが出た場合でも一概にコントローラの記述を見直すのではなくそれらに関連した記述を改めて絞って(今回はcontrollerとview)見直す必要があると思いました。
まだ完全に理解できたわけではないので違う解釈や説明があるとは思いますが、あくまで参考程度にみてもらえればと思います。

def destroy BlogComment.find_by(id: params[:id], blog_id: params[:blog_id]).destroy redirect_to public_blog_path(blog) end
### blog_comments_controller.rb 変更後 def destroy BlogComment.find_by(id: params[:id], blog_id: params[:blog_id]).destroy redirect_to public_blog_path(params[:blog_id]) end
### blogs/show.html.erb 変更前 <% if blog_comment.user == current_user %> <div> <%= link_to "削除", public_blog_blog_comment_path(blog_comment), method: :delete, class: "btn btn-danger pull-right" %> </div> <% end %>
### blogs/show.html.erb 変更後 <% if blog_comment.user == current_user %> <%= link_to "削除", public_blog_blog_comment_path(blog_comment.blog_id, blog_comment.id), method: :delete, class: "btn btn-danger pull-right" %> <% end %>

投稿2020/08/29 16:24

編集2020/08/29 16:28
KURUMAEBI

総合スコア2

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

<%= link_to "削除", public_blog_blog_comment_path(blog_comment), method: :delete・・・ %>
*blog_comment.comment ⇒ blog_comment へ変更

<%= link_to "削除", blog_comment, method: :delete・・・ %>

①または②とすることで、blog_commentpublic_blog_blog_comment_pathパス(Detroyアクション)へ送ることになるので、下記のようにすると期待した動作になるのではないかと思います。

def destroy @blog_comment.comment.destroy redirect_to public_blog_path(blog) end

投稿2020/08/29 10:15

no1knows

総合スコア3365

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

no1knows

2020/08/29 10:18

あ!回答がついていましたね。。。同じ結果を出すにもいろいろな方法があるのです。
KURUMAEBI

2020/08/29 13:32

すみません、どちらの方法も試してみたのですが、同じエラーが出てしまいます。 新しくblog_controller.rbの記述を載せたので総合して記述の間違いなどないか確認をお願いしたいです。 よろしくお願いします。
guest

0

link_to "削除", public_blog_blog_comment_path(blog_comment.comment)
なので、id しか送られていません。ですので
BlogComment.find_by(id: params[:id], blog_id: params[:blog_id]) が blog_id: nil になってしまい、一件もhitしない。
BlogComment.find_by(id: params[:id]) でどうぞ

投稿2020/08/29 10:05

winterboum

総合スコア23567

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問