form_tag の remote: true オプションってなに?
結論
オプションを指定すると、フォームの送信リクエストをAjax化してくれる。
Ajax って?
Asynchronous JavaScript and XML の略。Asynchronousって非同期って意味はわかるけど、なんて発音するんだろう。エイスィンクロネス?
とにかく JavaScript を使って、非同期処理を行う技術のこと。
なぜに XML(Extensible Markup Language)? って思ったけど、昔は XML を使う場合が多かったから、末尾には XML がついてるらしい。今は Json の方が多いと思うけどね。ずっと名前を使ってもらえるところが、XML の既得権益感があっていい。
How to use Ajax
ちなみに、Ajax を使った最もシンプルな書き方が簡単な通信処理は以下のような感じ。XMLHttpRequestっていうのは、JavaScript でサーバーと通信するために必要な組み込みオブジェクト。
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/posts', true);
xhr.setRequestHeader('Accept', 'application/json');
xhr.onreadystatechange = () => {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
const posts = JSON.parse(xhr.responseText);
const ul = document.getElementById('posts-list');
ul.innerHTML = posts.map(p => `<li>${p.title}</li>`).join('');
} else {
console.error('Error:', xhr.status, xhr.statusText);
}
}
};
xhr.send();
でも、なんかコールバックベースで、上のコードはイケてないでしょ?
なので、イケてるエンジニアたちが頑張ったおかげで、ES2015以降は fetch() みたいな Promise ベースの HTTPリクエストAPIでシンプルにかけるようになった。
fetch('/api/posts', {
headers: { 'Accept': 'application/json' }
})
.then(res => res.json())
.then(posts => {
const ul = document.getElementById('posts-list');
ul.innerHTML = posts.map(p => `<li>${p.title}</li>`).join('');
})
.catch(err => console.error(err));
そして、近年は JQuery とかのライブラリとかからも簡単に Ajax を使える。
$.ajax({
url: '/api/comments',
type: 'GET',
dataType: 'json'
})
.done(data => {
$('#comments-list').empty();
data.forEach(c => {
$('#comments-list').append(`<li>${c.body}</li>`);
});
})
.fail((jqXHR, textStatus) => {
console.error('Error:', textStatus);
});
そして、Rails でもJavaScriptのイベントとして扱いたい!って思ったら、form_tag の remote: true みたいに、オプションを指定するだけで、Rails UJS が使えるようになってる。
え、Rails UJSって?
Rails UJS
Unobtrusive JavaScript を略して UJS。Unobtrusiveってマジで発音わからんのだけど、アンネトゥルースィブ?意味は「控えめな」とか「目立たない」とか。
つまり「とてもシャイなJS」ってこと。
だから、ビュー側でちょっとフォーム確認ダイアログを表示したいとか、送信ボタンの二度押しを防止したいとか、なんかそういう「ちょこっと必要なJS」の機能をバイディングしてくれる仕組み。そして、今回の remote:true による Ajax化も、その仕組みの一つ。
チョコザップみたいな感じ。あんまり激しいのはいらないけど、ちょこっとだけ…。
Discussion