link_to に :method => :delete を指定した時の動作
以下 Rails 3.2.2 について記述します。
scaffold 等で作られる削除のリンクは次のようになっていると思います。
<%= link_to 'Delete', users_path(@user), :method => :delete, :confirm => 'Are you sure?' %>
これと同じコードを手で書いて使おうとしたのですが、なぜか正しく動作せず、少しはまってしまいました。結論から言うと、このコードが生成するリンクタグを動作させるには最低限 jquery.js と rails.js を読み込む必要があります(もちろん、それらの動作に対応したブラウザを使う必要もあります)。
そういうわけで、上記のコードを用いる時はレイアウト等で
<%= javascript_include_tag "application" %>
と記述するのを忘れないように気をつけてください。
ここから細かい解説、上の link_to は次のようなタグに展開されます。
<a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a>
これを解釈して動作させているのが rails.js です。ソースが公開されているので、確認してみます。
https://github.com/rails/jquery-ujs/blob/master/src/rails.js
記事執筆段階では160行目からが該当箇所になります。
// Handles "data-method" on links such as: // <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a> handleMethod: function(link) { var href = link.attr('href'), method = link.data('method'), target = link.attr('target'), csrf_token = $('meta[name=csrf-token]').attr('content'), csrf_param = $('meta[name=csrf-param]').attr('content'), form = $('<form method="post" action="' + href + '"></form>'), metadata_input = '<input name="_method" value="' + method + '" type="hidden" />'; if (csrf_param !== undefined && csrf_token !== undefined) { metadata_input += '<input name="' + csrf_param + '" value="' + csrf_token + '" type="hidden" />'; } if (target) { form.attr('target', target); } form.hide().append(metadata_input).appendTo('body'); form.submit(); },
このように、本来 DELETE メソッドでアクセスした際に行われる削除のアクションを form タグから _method を指定して再現しています。CSRF 対策の hidden タグ埋め込みも行っているので csrf_meta_tags も記述しないと動作しないかと思ったのですが、開発環境で動かしている限り問題ないようでした。