railsでのmethodが効かなくなる問題
初めに、このエラーを調べるとlink_toをbutton_toに変更すると治るという記事がたくさんありますが、
button_toにしても根本的解決にはなりません。
railsで時々起こるmethodをdelete、もしくはpatchで指定をしているのにgetでリクエストが送られてしまう問題をこの記事では解説したいと思います。
エラーの例としては、
- ActiveRecord::RecordNotFound in UsersController#show Couldn't find User with 'id'=sign_in
- sign_outに飛ばしたつもりが、意図しないページに飛んでしまう(methodがgetになってしまうことが原因で)
実際に原因究明スタート
railsではどのようにdata-methodを動かしているのか?
railsでは、rails-ujs
を入れることによってhttp methodでdelete、patchを実現している。
標準のHTMLとしては、getとpostのみしか対応していないらしい...
rails-ujsについては、こちらの記事がわかりやすいと思います。
なので最初の確認事項としては、rails-ujs
が入っているか確認してみましょう!
確認箇所としては、
package.json
{
"name": "アプリケーション名",
"private": true,
"dependencies": {
~ 省略 ~
"@rails/ujs": "^6.0.0",
"@rails/webpacker": "5.4.0",
~ 省略 ~
},
"version": "0.1.0",
"devDependencies": {
"webpack-dev-server": "^4.9.0"
}
}
ここにrails-ujs
の記載がなければ導入をしてあげましょう!
package.jsonに直接編集しないでください
ターミナルにて実行↓
yarn add @rails/ujs
application.js
application.jsにて、import文があるか確認してあげましょう!
もしなければ直接編集してあげましょう!
+ import Rails from "@rails/ujs
他のinstallしたものの影響でapplication.jsに不備がないか?
application.jsに、不備がある場合も正しくrails-ujs
が動かなくなります。
どこに対して不備があるのかをいちいちpackage.json
と比較しながら見るのは面倒なのでコンパイルをかけて判断してあげましょう。
1. 過去のコンパイルの結果を削除してから、立ち上げる
$ rm -rf public/packs/js/
2. コンパイルを強制的にかける
$ bin/webpack
rails webpacker:compile
でもコンパイルをかけられますが、コンパイルがかからない場合があります。
過去のコンパイルを削除するのが一番確実にコンパイルをかけられます。
コンパイルをかけた際のエラー例
下記の画像は、application.jsにわざと適当な文字列を挿入した場合のコンパイル結果になります
上記の画像のエラーが消えるように、スペルミスの修正やコンパイルが正常にかけられない原因を除去してあげましょう。
headタグでapplication.jsが読まれているのか?
コンパイルが正常に動作しても、肝心のapplication.jsが使われていなければ全く意味がありません。
ここでは、ちゃんとapplication.html.erbの中でapplication.jsが読まれているのかを確認していきましょう。
application.html.erbのheadタグ内を確認
<head>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
// javascriptの読み込みがあるか確認↓
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>
立ち上げた画面の検証ツールのhead内を確認
head内でscriptタグの中で、packsからapplication.jsが呼び出されているのかを確認する。
もし、head内が空の場合
- ターミナルでapplication.html.erbが読まれているか確認
最初に$rails s
をした際に、layouts/application.html.erbというファイルが読まれているか確認する。
おそらくこの読み込みがないのが原因で、headの中身が空になっている。
ここからは、application.html.erbが読まれない原因を探る必要があります。
正直ここからはスペルミスだったりが原因となることが多いのでその辺を重点的に探してみてください。
前自分が見つけたことがあるのは、フォルダ名がlayout
になってしまっていて、layouts
から呼び出したいのにそのフォルダが見つからずスルーされてしまっていたということがありました。おそらくその辺にエラーがあると思うので確認してみてください
一応検証ツールの結果も確認しておく...
上記のコンパイルがしっかりとエラーなく通っていれば問題はないはずですが、一応エラーがないか確認しておきましょう!
link_toがちゃんと正しいaタグのdata_methodで作成されているか
data_methodが正常か確認!
スペルミスの確認....
スペルミスの確認ですが、意外にもよくあるんですよね。
- methodのスペルミス
method
がmethood
になっている
link_toの場合、methodはオプションなのでスペルミスをしてもエラーが出ず、無視される → デフォルトのgetを使用してしまう。
- 存在しないmethodを指定している。
method: :destroy
← 正しくはmethod: :delete
上記のmethodのスペルミスと同じでオプションなので、認識できなければ無視される
最後に.....
あまり見たことないけど、methodを大文字で書かないといけないもしくは、小文字じゃないと反応しない。
これまでの確認事項を全てクリアしたうえで動かなければ、method: :delete
とmethod: :DELETE
両方で記述を
試してみてください。
これ以外に要因あるかな...??
思い当たるのがないので、もしある方はコメントください