コメント機能実装の際に詰まった。 [Rails,Ruby,binding.pry]


環境

ruby 2.6.5
rails 6.0.0
MySQL
Github

発生したエラー

コメント機能の実装の際、投稿後のリダイレクトに関する記述の部分で以下のエラーが発生

No route matches {:action=>"show", :controller=>"boards", :id=>nil}, missing required keys: [:id]

その時のコードは以下の通りです。

show.html.erb
<%= form_with(model: [@board, @comment], local: true) do |f| %>
        <%= f.text_area :text, id:"text" %>
        <%= f.submit "SEND" %>
    <% end %>
comments_controller
class CommentsController < ApplicationController

  def create
    @comment = current_user.comments.build(comment_params)
    if @comment.save
      redirect_to board_path(params[:id]) #エラー発生部分
    else
      redirect_to board_path(params[:id])
    end
  end

  private
  def comment_params
    params.require(:comment).permit(:text).merge(user_id: current_user.id, board_id:params[:board_id])
  end
end

エラー解決までの過程

解決までの過程ですが、binding.pryのゴリ押しで解決まで至りました。

まず、エラー文から想定するに、[id=>nil]と記載があるので、boardのidの受け渡しがうまくできていません。
binding.pryを使いターミナルを見てみます。

以下の場所にbinding.pryを置きます。

comments_controller
class CommentsController < ApplicationController

  def create
    @comment = current_user.comments.build(comment_params)
    binding.pry #こちらにおきました
    if @comment.save
      redirect_to board_path(params[:id])
    else
      redirect_to board_path(params[:id])
    end
  end

  private
  def comment_params
    params.require(:comment).permit(:text).merge(user_id: current_user.id, board_id:params[:board_id])
  end
end

ターミナルでストロングパラメーターであるcomment_paramsを確認します。

terminal
[1] pry(#<CommentsController>)> comment_params
Unpermitted parameter: :board_id
=> <ActionController::Parameters {"text"=>"あああ", "user_id"=>5, "board_id"=> 
 "2"} permitted: true>
[2] pry(#<CommentsController>)> 

怪しい点が1カ所あります。以下の箇所です。

Unpermitted parameter: :board_id

Unpermittedと表記されています、つまりboard_idが拒絶されています。

ストロングパラメーターに関する記述を再度確認します。

comments_controller
 private
  def comment_params
    params.require(:comment).permit(:text).merge(user_id: current_user.id,
 board_id:params[:board_id])
  end
end

今回は、commentテーブルのカラムにboard_idを設定しているので、mergeさせる予定でしたが、ターミナルではUnpermittedとなっており、board_id拒絶されています。
なので、permitメソッドの部分を修正します。

comments_controller
  private
  def comment_params
    params.require(:comment).permit(:text,:board_id).merge(user_id: current 
 _user.id, board_id:params[:board_id])
  end

ではもう一度、binding.pryでターミナルにて確認します

terminal
[1] pry(#<CommentsController>)> comment_params
=> <ActionController::Parameters {"text"=>"あああ", "board_id"=>"2", "user_id" 
 =>5} permitted: true>

Unpermittedが消えてます。

これでエラーが発生しないと思いきや、再び同じエラーが発生しました。
お気づきの方もいらっしゃるかもしれませんが、以下の点が間違っています

comments_controller
 if @comment.save
      redirect_to board_path(params[:id])#idではない
    else
      redirect_to board_path(params[:id])#idではない
    end

結論としてはparams[:id]ではございません。
では、何を記述すれば良いかをもう一度binding.pryをして確認してみましょう

[1] pry(#<CommentsController>)> params
=> <ActionController::Parameters {"authenticity_token"=>"ClGuWdi+9RzHuFZ7JgWEm
/m9iLi0IS+o9Cdyfu5uOknOAzgcK9cvFJhzAPCsKSy3rVwUC7xS9Mi2xNjpvGEChg==", "comment"
=><ActionController::Parameters {"text"=>"aaa", "board_id"=>"2"} permitted:
 false>, "commit"=>"SEND", "controller"=>"comments", "action"=>"create", 
"board_id"=>"2"} permitted: false>

ご覧の通り、idに関するパラメーターは存在しておりません。
正しくは以下のようにboard_idと記述するのが正解です。

comments_controller
 if @comment.save
      redirect_to board_path(params[:board_id])
    else
      redirect_to board_path(params[:board_id])
    end

これで無事にコメント投稿機能を実装できました。

まとめ

binding.pryを使った、エラー解決の一連の流れを記載させていただきました。
経験談ですがパラメーター関係のエラーはbinding.pryで大体解決できると思います。
ご指摘等ありましたら、お気軽にご連絡ください。
長文となりましたが、ここまで読んでいただきありがとうございました。