##はじめに
投稿系のアプリケーションを作成中、Rails5.2にwebpackerを導入した途端、元から実装してあったログアウト機能が動作しなくなりました。
no route matches [get] "/logout"
エラーが出てdeleteリクエストを送信できなくなってしまったので、これを解決します。
##環境
Ruby 2.6.5
Rails 5.2.4.2
webpacker 5.1.1
##エラー発生地点
webpackerビルド後に、application.html.slimにwebpackerのスクリプトタグを読み込んだ瞬間から。
head
.
.
.
- = javascript_include_tag 'application','data-turbolinks-track': 'reload'
+ = javascript_pack_tag 'application'
.
.
.
##解決策
1.まずはyarnのパッケージファイルにrails-ujs
を追加します。そしてpackage.jsonにこれが追加されていることを確認します。
$ yarn add rails-ujs
{
"name": ,
"dependencies": {
"@rails/webpacker": "5.1.1",
"rails-ujs": "^5.2.4-3",
},
}
2.app/javascript/packsディレクトリ配下にrails-ujs.js
ファイルを作成し、下記の記述を追加します。
import Rails from 'rails-ujs';
Rails.start();
3.app/javascript/packs/application.jsファイルに、rails-ujs.jsファイルを読み込ませます。
require("./rails-ujs.js");
4.app/views/layouts/application.html.slimファイルに、webpackerスクリプトを記述します。
head
.
.
.
= javascript_pack_tag 'application'
.
.
.
以上で、DELETEリクエストを受けてくれるようなったかと思います。
###何故これで動作するのか
色々調べた結果、辻褄を合わせただけのため断言はできませんが、こうだろうみたいな予想を立ててみました。
もし間違っていたら、ご指摘して頂けるととてもありがたいです!
まず前提として、デフォルトの状態ではHTMLはGET,POSTのリクエストを送信することしかできません(なのでログインなどは通常通り行えます)
しかしRailsにてDELETE,PATCHなどのRESTful APIを発行する場合は、JavaScriptに処理を任せているためgem rails-ujs
もしくはgem jquery-rails
を用いています。
Rails5.1以降ではJavaScriptの統括ファイルにこのrails-ujsがデフォルトで読み込まれています
(下記ファイルを参照)。
なので我々は特に気にしなくとも、ただRails側でmethod: :deleteなどのオプションを記述すれば、あとはJavaScriptが勝手に処理してくれるため、HTMLからDELETEリクエストを送信することができるようになっています。
ちなみにjquery-ujsはRails5.1以降サポートが廃止されています(Railsガイドより。)
//= require rails-ujs
//= require activestorage
//= require turbolinks
//= require_tree .
しかしwebpackerを導入すると、デフォルトの状態ではrails-ujsがそもそも導入されていないので、サポートを受けることができません。
なのでrails-ujsを導入し、packs/application.jsファイルに新たにrails-ujs読み込みさせてあげなければ、RESTfulなAPIの処理を使用できないのは当然だったのかなと思いました。
##参考
http://docs.komagata.org/5456
https://www.inodev.jp/entry/2019/12/03/234210