Rails3.0.4で、link_to ヘルパーメソッドにconfirmやmethodを混ぜるときの注意
Rails3.0.4以前のRails3系で、link_toヘルパメソッドにconfirmとmethodを混ぜていると、ブラウザによっては想定していない挙動をすることがあります。
<%= link_to "削除", {:action => :delete, :id => item_id},
:confirm => "本当に削除しますか?", :method => :delete %>
というようなコードを書いて確かめると、Firefox等では問題がないのにIEだとconfirmでキャンセルを選択してもdeleteアクションが実行されてしまいました。
このあたりの挙動は、rails.jsの中で実装されています。
document.on("click", "*[data-confirm]", function(event, element) {
var message = element.readAttribute('data-confirm');
if (!confirm(message)) event.stop();
});
document.on("click", "a[data-remote]", function(event, element) {
if (event.stopped) return;
handleRemote(element);
event.stop();
});
document.on("click", "a[data-method]", function(event, element) {
if (event.stopped) return;
handleMethod(element);
event.stop();
});
調べてみると、IEのときは先に data-methodの関数がコールされていました。どのイベントが先に呼ばれるかはブラウザによるようです。
Railsのedgeを調べてみるとrails.jsがなくなっていて、prototype_ujs.jsというところで実装されていました。
document.on('click', 'a[data-confirm], a[data-remote], a[data-method]', function(event, link) {
if (!allowAction(link)) {
event.stop();
return false;
}
if (link.readAttribute('data-remote')) {
handleRemote(link);
event.stop();
} else if (link.readAttribute('data-method')) {
handleMethod(link);
event.stop();
}
});
allowActionという関数は、confirmがあればそれをコールして結果を返します(なければtrueが返ります)。ひとつの関数で、三つの挙動を行うように修正されています。
なので、Rails3.0.4でもこのあたりのコードをもってくるとよさそうです。
ちなみにegdeのRailsではjQueryも標準で含まれていました。もっと早く取り入れてほしかったですが、楽しみにしてまっていましょう。