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

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

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

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

Ruby on Rails

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

Q&A

1回答

694閲覧

写真投稿にネストしたコメントを削除しようとすると、エラーが出てしまいます……

you-key

総合スコア2

Ruby

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

Ruby on Rails

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

0グッド

0クリップ

投稿2021/09/30 08:06

編集2021/09/30 14:40

前提・実現したいこと

rails で簡単な写真の投稿アプリを作っています。
写真の詳細画面に表示させたコメントを削除したいです。
写真とコメントはそれぞれ違うモデルを用意し、ネストしてます。

色々試して、何回もエラーに当たってしまって行き止まってます……

発生している問題・エラーメッセージ

NoMethodError in CommentsController#destroy undefined method `join' for {:id=>"23", :photo_id=>"1"}:Hash Extracted source (around line #18): 16  17   def destroy 18  comment = Comment.find(id: params[:id], photo_id: params[:photo_id]) 19  if comment.destroy 20   redirect_to photo_path 21  end Application Trace | Framework Trace | Full Trace app/controllers/comments_controller.rb:18:in `destroy' Request Parameters: {"_method"=>"delete", "authenticity_token"=>"qDVivY7XxyOKCxG+OxDXwu39jwOW62hs8KEvvqG2DwPft6gwFl3SKVUTJnWP6h57BU7rynDK/4KmRdjbQikhCw==", "photo_id"=>"1", "id"=>"23"}

該当のソースコード

ruby

1class CommentsController < ApplicationController 2 def new 3 @photo = Photo.find(params[:photo_id]) 4 comments = Comment.all 5 comment = Comment.new 6 end 7 8 def create 9 @photo = Photo.find(params[:photo_id]) 10 comment = Comment.new(comment_params) 11 if comment.save 12 ActionCable.server.broadcast 'comment_channel', content: comment 13 end 14 render :json => comment 15 end 16 17 def destroy 18 comment = Comment.find(id: params[:id], photo_id: params[:photo_id]) 19 if comment.destroy 20 redirect_to photo_path 21 end 22 end 23 24 private 25 26 def comment_params 27 params.require(:comment).permit(:text).merge(user_id: current_user.id,photo_id: params[:photo_id]) 28 end 29end 30

ruby

1class PhotosController < ApplicationController 2 before_action :find_params, except: [:index, :new, :create] 3 before_action :authenticate_user!, only: [:new, :edit] 4 5 6 def index 7 @photos = Photo.order(created_at: :desc) 8 end 9 10 def new 11 @photo = Photo.new 12 end 13 14 def create 15 @photo = Photo.new(post_params) 16 if @photo.save 17 redirect_to root_path 18 else 19 render :new 20 end 21 end 22 23 def show 24 @comment = Comment.new 25 @comments = @photo.comments.includes(:user) 26 end 27 28 def edit 29 end 30 31 def update 32 if @photo.update(post_params) 33 redirect_to root_path 34 else 35 render :edit 36 end 37 end 38 39 def destroy 40 if @photo.destroy 41 redirect_to root_path 42 end 43 end 44 45 private 46 47 def find_params 48 @photo = Photo.find(params[:id]) 49 end 50 51 def post_params 52 params.require(:photo).permit(:image, :title, :category_id).merge(user_id: current_user.id) 53 end 54end 55

ruby

1#photos/show.html.erb 2 3<div class="show-comments"> 4<div class="submit-comment"> 5 <% if user_signed_in? %> 6 <%= form_with(model:[@photo, @comment]) do |f| %> 7 <%= f.text_field :text, class:"submit-field" %> 8 <%= f.submit "ボケる" , class:"submit-btn" %> 9 <% end %> 10 <% else %> 11 <strong><p>※※※ コメントの投稿には新規登録/ログインが必要です ※※※</p></strong> 12 <% end %> 13 </div> 14 <h1 class="list-comment">みんなのボケ一覧</h1> 15 <div class="comments", id='comments'> 16 <% @comments.reverse_each do |comment| %> 17 <div class="comment-area", id="comment-area"> 18 <p class="comment"><%= comment.text %></p> 19 <p class="comment-user"><%= comment.user.nickname %></p> 20 </div> 21 <div class="delete-area"> 22 <% if user_signed_in? && current_user.id %> 23 <%= link_to "削除", photo_comment_path(comment.photo_id, comment.id), method: :delete, class:"comment-delete-btn", id:"comment-delete-btn" %> 24 <% end %> 25 </div> 26 <% end %> 27 </div> 28</div> 29

ruby

1Rails.application.routes.draw do 2 get 'comments/new' 3 devise_for :users 4 root to: 'photos#index' 5 resources :photos do 6 resources :comments, only:[:new, :create, :destroy] 7 end 8 resources :users 9end 10 11

ruby

1class Comment < ApplicationRecord 2 belongs_to :photo 3 belongs_to :user 4 5 validates :text, presence: true 6end 7

ruby

1class Photo < ApplicationRecord 2 has_one_attached :image 3 belongs_to :user 4 has_many :comments 5 6 extend ActiveHash::Associations::ActiveRecordExtensions 7 belongs_to :category 8 9 with_options presence: true do 10 validates :title 11 validates :image 12 validates :category_id , numericality: { other_than: 0 } 13 end 14 15end 16

ruby

1class User < ApplicationRecord 2 # Include default devise modules. Others available are: 3 # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable 4 devise :database_authenticatable, :registerable, 5 :recoverable, :rememberable, :validatable 6 7 with_options presence: true do 8 validates :last_name 9 validates :first_name 10 validates :nickname, length: { maximum: 8 } 11 validates :email, uniqueness: {case_sensitive: true} 12 validates :password, length: { minimum: 6 }, format: { with: /\A(?=.*?[a-z])(?=.*?\d)[a-z\d]+\z/i } 13 end 14 15 has_many :photos 16 has_many :comments 17end 18

試したこと

CommentControllerのdestroy アクション内、18行目、

comment = Comment.find(id: params[:id], photo_id: params[:photo_id])

この書き方を色々試しました

******

①comment = Photo.find(id: params[:id], photo_id: params[:photo_id])

NoMethodError in CommentsController#destroy undefined method `join' for {:id=>"24", :photo_id=>"1"}:Hash Extracted source (around line #18): 16 17 def destroy 18 comment = Photo.find(id: params[:id], photo_id: params[:photo_id]) 19 if comment.destroy 20 redirect_to photo_path 21 end

②comment = @photo.comments.find(id: params[:id], photo_id: params[:photo_id])

NoMethodError in CommentsController#destroy undefined method `comments' for nil:NilClass Extracted source (around line #18): 16 17 def destroy 18 comment = @photo.comments.find(id: params[:id], photo_id: params[:photo_id]) 19 if comment.destroy 20 redirect_to photo_path 21 end

  この書き方では、「comments」を認識してくれなさそう
PhotoControllerに「comment = Comment.find(params[:id]」とか書いてみたけど、変化なし

③comment = Comment.find(comment_id: params[:comment_id], photo_id: params[:photo_id])

NoMethodError in CommentsController#destroy undefined method `join' for {:comment_id=>nil, :photo_id=>"1"}:Hash Extracted source (around line #18): 16 17 def destroy 18 comment = Comment.find(comment_id: params[:comment_id], photo_id: params[:photo_id]) 19 if comment.destroy 20 redirect_to photo_path 21 end

  binding.pryでparams[:comment_id]を確認。
これが「Nill:class」になってしまっていました。
comment_idを渡してあげたいけど、どうしてもその方法がわからず……

*******

色々調べて、色々試しましたが、エラーが変われど、どれもうまくいかず……
あと、何を試せるでしょうか……

おしえていただきたいです。
よろしくお願いします。

補足情報(FW/ツールのバージョンなど)

ruby '2.6.5'
rails '~> 6.0.0'

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

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

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

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

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

winterboum

2021/09/30 13:57

エラーメッセージは省略しないで全文を載せてください。 有用な情報が欠落してしまいますから
you-key

2021/09/30 14:41

ご指摘、ありがとうございます。 確かにその通りです。 質問をするにあたり、認識が甘かったことを反省しております。 まだ完璧にかけているかは自信ありませんが、 もしお知恵をお貸しいただけるなら、何卒よろしくお願いいたします。
guest

回答1

0

find ではなく find_by を使ってください

投稿2021/09/30 22:38

winterboum

総合スコア23416

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問