控えめなJavascript(rails-ujs)のおかげで、DELETEなどのHTTPリクエストができるみたい

June 24, 2020

こんにちは、たわらです。

本記事は、控えめな Javascript についての情報をまとめました。

ことの発端

最近、開発者ツールを使うことを覚えてたので、ログアウト機能を実装するときに、HTML 構造を確認しました。

<a class="nav-link" rel="nofollow" data-method="delete" href="/admin/logout"
  >ログアウト</a
>

できてますね。

で、挙動の確認をしようと思って、開発者ツールの/admin/logoutをクリックすると、

No route matches [GET] "/admin/logout"

とエラーが出てきます。ルーティングもあってるし、

<%= link_to "ログアウト", admin_logout_path, class: "nav-link", method: :delete %>

delete もちゃんと指定できてるのに、なんで??? となってしまいました。

で、ブラウザのログアウトボタンを押すと、きちんとログアウトができました。なんで???

a タグの基本は GET リクエスト

で、講師の方に質問すると、「ざっくり説明すると、HTML 上のルールとして、a タグは GET メソッドなんだよね」と教えてもらいました。だから、開発者ツールのリンクを踏むと、GET メソッドで HTTP リクエストが発行されるのですね。

ほえー、なるほど。じゃ、どうして DELETE メソッドが使えるの?

講師「ブラウザ上のログアウトボタンを押したときには、rails-ujs という Javascript が機能して、delete や post としてリクエストができるようになっているよ」

なるほど。

マニフェストファイルの application.js にあるこの行のことですね

//= require rails-ujs

控えめな Javascript の登場

で、調べてみると Rails ガイドに、

Rails では、JavaScript を DOM に追加する際の手法を「UJS: Unobtrusive(控えめな)JavaScript」と呼んでいます。これは一般にフロントエンド開発者コミュニティでベストプラクティスであると見なされていますが、ここではもう少し違う角度から説明したいと思います。

と記載がありました。

この名称は、HTML の中に JavaScript を混入させないという意図に由来しています。JavaScript を正しく分離できたので、今後の変更が楽になります。以後は、このdata-*属性をリンクタグに追加するだけでこの動作を簡単に追加できます。Rails では、こうした「最小化」と「連結」によって、あらゆる JavaScript を実行できます。

data-method="delete"とすると、よしなにやってくれるみたいです。

なので、マニフェストファイルに

//= require rails-ujs

を記述しないと、うまく作動してくれないようです。

もっと気になるかたは、この記事がわかりやすかったです。

link_to によって delete メソッドなどをa タグで実装できているように感じますが、実際には rails-ujs が動的に form を組み立てて送信しているという動作になります。

ということを Rails の内部のコードに触れながら解説してくれます。

https://www.inodev.jp/entry/2019/12/03/234210

最後に

rails-ujs によって、method: :delete などのオプション指定を鑑みて、HTTP リクエストを発行してくれるのですね。

読んでくださったかた、どうもありがとうございます。

参考文献

https://www.inodev.jp/entry/2019/12/03/234210

https://railsguides.jp/working_with_javascript_in_rails.html#%E3%80%8C%E6%8E%A7%E3%81%88%E3%82%81%E3%81%AAjavascript%E3%80%8D