ajaxでのコメント機能実装時のエラー②(UrlGenerationError)
UrlGenerationError
今回の実装において最も苦戦したエラー。 一見簡単そうに見えるエラーなのだが、かなりの曲者だった。
# ActionController::UrlGenerationError: # No route matches {:action=>"show", :controller=>"comments", :id=>nil}, missing required keys: [:id]
簡単にいうと、「必要なidが渡されていないので、commentsコントローラーのshowアクションにルーティングできないよ〜」ということらしい。
しかし、今回コメントはboards/showの中に埋め込んでいるためcommentsのビューファイルが不要なので実装しておらず、commentsコントローラーのshowアクションも当然未実装。。。どういうことなの。
rails routes
で現在のルーティングを調べてみる。
comment GET /comments/:id(.:format) comments#show PATCH /comments/:id(.:format) comments#update PUT /comments/:id(.:format) comments#update DELETE /comments/:id(.:format) comments#destroy
Showアクションへのpathであるcomment_pathと同じものはこの4種類。
この中で、deleteアクションへのリンクだけlink_toメソッドでmethod: :delete, remote: true
を使って実装したのでここが怪しいと推測。
Rspecのファイルをアプリケーション内に落とし、ローカル環境で回してみた。
1) コメント コメントのCRUD コメントの作成 コメントの作成に失敗すること Failure/Error: <%= link_to comment_path(comment), method: :delete, remote: true do %> ActionView::Template::Error: No route matches {:action=>"show", :controller=>"comments", :id=>nil}, missing required keys: [:id] [Screenshot]: tmp/screenshots/failures_r_spec_example_groups_nested_3_crud_nested_2_コメントの作成に失敗すること_105.png
やはり推測通り、原因は<%= link_to comment_path(comment), method: :delete, remote: true do %>
で間違い無いらしい。
なんらかの理由でgetリクエストも送られているみたい。
しかし、このコードの何が間違っているのか全く分からず… そもそも削除機能自体は正しく実装されており、ajaxでも正しく動作し、またデータベースからもしっかりと削除されているのを確認している。
①comment_path(comment)
=> comment_path(comment.id)
に変更
②comment_path(comment)
=> /comments/#{comment.id}/
に変更
上記の2つを試しても駄目だった。
ちなみに、showアクションと簡単なビューを作成し、method: :deleteを削除してgetリクエストを送ってみると、ちゃんと適切なコメントが表示された。
comment_path(comment)
でちゃんと:id渡せてるやん。。。
お手上げかと思われたが、ここで妙なことに気づく。
1) コメント コメントのCRUD コメントの作成 コメントの作成に失敗すること
コメントの削除に成功すること というテスト項目で、このコードが指摘されるのはわかるが、なんでこのテスト項目でこのコードが指摘される? 試しにcommentのbodyが空の状態で投稿してみる。
なんと同じメッセージが表示されている!!!!
適切な例外処理ができていないことが原因????
ということで、create.js
をifで分岐させてエラーメッセージを表示させることに。
$('#js-table-comment').prepend("<%= j(render 'comment',{ comment: @comment }) %>"); $('#comment_body').val('')
$("#error_messages").remove() <% if @comment.errors.present? %> $("#new_comment").prepend("<%= j(render('shared/error_messages', object: @comment)) %>") <% else %> $('#js-table-comment').prepend("<%= j(render 'comment',{ comment: @comment }) %>"); $('#comment_body').val('') <% end %>
さぁどうだろう・・・
エラー出てない!!!!!!
恐る恐るrspecを回してみると・・・
test@tesutonoMacBook-Air 552_yukimura907_runteq_learning_basic % bundle exec rspec .....................Capybara starting Puma... * Version 3.12.1 , codename: Llamas in Pajamas * Min threads: 0, max threads: 4 * Listening on tcp://127.0.0.1:51124 ..................................... Finished in 22.15 seconds (files took 3.01 seconds to load) 58 examples, 0 failures
成功!!!
スタバでガッツポーズした。
今回のエラーを通して、本当に厄介なのはメッセージとは全く違うコードが原因で引き起こされているエラーだと気づいた。
我ながらよくこのエラーを自力解決できたなーと思う。
意地でも自力走破してやろうと半ば躍起になっているが、そのおかげで自走力がだいぶ付いてきた気がする。