ある特定の条件のユーザーのみ、railsで作成したルームからコメントを投稿しようとすると下記のようなエラーが出て、解決したのでアウトプットします。「undefined method `model_name' for nil:NilClass」
エラー発生の経緯
<%= form_with(model:[@room, @comment], local: true) do |f|%>
<%= f.text_area :text, placeholder:"コメントを入力してください" ,class:"comment_box"%>
<%= f.submit '送信', class:"comment_bottom_r"%>
<%end%>
上記のような記述でコメント送信ボタンを押すと、undefined method `model_name' for nil:NilClassとエラーが出ます。投稿フォームでこのようなエラーが出る場合、考えられる原因を列挙すると、
・ルーティングがネストになっていないなどの不備がある。
・comment.htmlにスペルミスがある
・comment.htmlに遷移する前に、コントローラー内でコメントのインスタンスを発行していない。
・form_withに適切な変数を渡していない
などが考えられます。従って、routes、コントローラーを確認します。
Rails.application.routes.draw do
resources :rooms do
resources :comments,only:[:show, :create, :destroy]
end
end
routesはちゃんとネスト等も組んでおり問題ありませんでした。次にコントローラーを確認します。コメント打ち込む場所がshow.htmlですので、そこに遷移するためのコントローラー内のshowアクションで、しっかりとインスタンス変数を生成しているか確認します。
def show
@room = Room.find(params[:id])
@comment = Comment.new
end
Comment.newで空のインスタンス変数は生成しています。以上より確認した場所では特に問題がないことがわかりました。
エラーの内容
undefined method `model_name' for nil:NilClassをアバウトに日本語訳すると、nilclassであるmodel_nameというメソッドを定義していないというもの。model_nameというメソッドが原因なのはわかりましたが、そもそもmodel_nameなんてもの定義していませんし、触れてすらいませんし、検討がつきません。結局はいろいろなパターンを総当たりして、解決しました。
エラー解決方法
結論から言うと、commentsのcraeteアクション内で、再度"@comment = Comment.new"を定義し直すと、エラーが出ないようになりました。
class CommentsController < ApplicationController
before_action :authenticate_user!
def create
@comment = Comment.new #この行を追記。
@room = Room.find(params[:room_id])
if find_user_positioin != nil
if Comment.create(comment_params)
redirect_to room_path(@room)
else
create_comments
render 'rooms/show'
end
else
create_comments
render 'rooms/show'
end
end
確かな原因はわかりませんでしたが、送信する際にコメントのインスタンス変数をどこかに落としてしまって、エラーが出たのかなと思います。もしかしたら、sessionなんかが絡んでいるのかもしれません。