1
0

More than 3 years have passed since last update.

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

Last updated at Posted at 2021-02-11

環境

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で大体解決できると思います。
ご指摘等ありましたら、お気軽にご連絡ください。
長文となりましたが、ここまで読んでいただきありがとうございました。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0