4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Rails で HTTP DELETE メソッドを使える条件

Last updated at Posted at 2020-05-18

はじめに

Rails では RESTful な設計とするために各種 HTTP リクエストメソッドを使い分けていて、config/routes.rb では当たり前に DELETE メソッドを定義すると思います。

が、このルーティング、正しく機能するためには条件があります。その条件を満たしていないと正しく動作しません。

結論

jquery-ujs.js もしくは rails-ujs.js が読み込まれていることが条件です。これら JavaScript が__トリックによって DELETE をエミュレート__しています。

トリックの正体と有効/無効

一般的にブラウザでは GET と POST しか使えません。DELETE リクエストは送信されないので、当該ルートが発現することはありません。例えば link_to method: :delete と書いたとしてもブラウザの素の能力では GET が送信されてしまい、最悪誤動作を引き起こします。

そこで前述 JavaScript が上手いことやって「DELETE のつもりでリクエストするんだぜ」というのを伝えることで、DELETE メソッドではないものの DELETE ルートを発現させています。具体的には form オブジェクトを作って「本来の意図は DELETE だよ」というパラメータを添えて POST しています。

そしてこのトリックは普通に rails new すれば自動的にお膳立てされ有効になります。

が、rails new --skip-javascript すると無効になります。JavaScript に依存しているんだから当たり前ですね。そして前述のように link_to method: :delete は GET になってしまうのです。

手作業でトリックを有効にする方法

何らかの事情で rails new --skip-javascript しなければならない場合に手作業でトリックを有効にする方法は、下記です。各ファイルに各行を追記します。

app/assets/javascripts/application.js
//= require rails-ujs
app/views/layouts/application.html.erb
    <%= javascript_include_tag 'application' %>

別法あります

ここまでは前置きです。
ここからが本題です。

JavaScript を使わなくても DELETE ルートを使うことは出来ます。button_to method: :delete です。

JavaScript が生成している form を静的に生成すればいいわけです。

より link_to ぽく

button_to では input type='submit' が1つ(と input type='hidden' が幾つか)の form が生成されますが、class='button_to' になっています。さらに例えば button_to class: :anchor とすると input type='submit' class='anchor' になります。

生成される.html
<form class="button_to" method="post" action="/logout">
  <input type="hidden" name="_method" value="delete" />
  <input type="hidden" name="authenticity_token" value="ナイショ" />
  <input class="anchor" type="submit" value="LOGOUT" />
</form>

なので、下記のような CSS (SCSS) を書いてやれば、機能も見た目も link_to の代わりに使うことが可能です。

app/assets/stylesheets/custom.scss
form.button_to {
  display: inline;

  input.anchor[type='submit'] {
    border-style: none;
    padding: 0;
    font-size: 1em;
    cursor: pointer;
    background-color: $bg-color;
    color: $link-color;
  }
}

終わりに

もともと --skip-javascript なんて使ってなかったんですが、Rails 6 が Webpacker で yarn や node_modules 必須になってたものの取り急ぎ小さく new したかったので --skip-javascript したら一旦良さそうだったけど logout 出来ず「!?」となって、、、ここに至りました。

静的最高♪

4
5
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
4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?