Help us understand the problem. What is going on with this article?

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

はじめに

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 出来ず「!?」となって、、、ここに至りました。

静的最高♪

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした