2016年09月01日

Railsでのajax通信を最小限のプロジェクトで把握する

Ajaxという技術が当たり前のように使われているWebの世界にいますが、正直Ajaxが何なのか、最近までよくわかっていませんでした。
今携わっているアプリでもAjaxは当たり前のようにあちこちで使われており、いい加減はっきりさせておかないと学習の期を失うと思ったので、アプリのコードをほじくり返して何が行われているのか勉強しました。

コード読むだけでもわかるのですが、せっかくなのでまっさらなプロジェクトを作成して、わかりやすい形で残しておこうと思います。

そもそもAjaxとは何なのか

安心も信頼もイマイチできないけど、とりあえず一番最初に引っかかるwikipediaさんを見ると、以下のように書いてある。

ウェブブラウザ内で非同期通信を行いながらインターフェイスの構築を行うプログラミング手法

うん、予想通りよくわからん。

仕方ないので他のページを見に行くと、このページの解説がわかりやすかったです。
すごくざっくり言うと「画面内で必要な分だけサーバーと通信してデータをやり取りする手法」のことのようです。

そしてAjaxは何か特定のアプリやソフトウェアを示すのではなく「何かをWeb上で表現する実現方法の1つ」だそうです。

なるほど、確かに今触ってるアプリでもそんな感じでした。

Rails上でのAjax

では本題です。
Railsの上ではどのようにAjaxが使われているのでしょうか。

僕はコード読んでいて驚いたのですが、RailsではView側のヘルパータグ( form_tag とか link_to とか)で remote: true を指定するだけで、該当する操作をAjax化してくれます。

これだけでは何が何だかって感じなので、新しいRailsプロジェクトを作成して、順番に把握していきます。

Ajaxサンプルアプリを作ってみる

今回は本当に最小限な動作でAjaxを確認します。
「indexページにあるボタンを押すと、DBからデータを取ってきて画面内の要素にデータを書き込む」だけのアプリです。

  • まずrails newする
  • rails g scaffold user name:string を実行してモデルを作る
  • views/users/index.html.erbに、 <%= link_to 'Run Ajax', ajax_path, remote: true %> のようなリンクを作成します
  • さらにindexに、Ajaxで取ってきたデータを書き込むための空のdivを作成します <div class="ajax"></div>
  • 上記リンクで指定したパスのroutesを定義しますので、routes.rbに get "/ajax" => "users#ajax" を追加します
  • コントローラにAjaxにより呼び出されるアクションを定義(users#ajax)します。 今回はサンプルなので、とりあえずユーザーデータを取得するようにします。
def ajax
  # ユーザーを登録しておいてください
  @users = User.all
end
  • Ajax用のerbファイルが必要なので、views/users/ajax.js.erb を作成します。 中身は以下のようにします。
$(".ajax").append(
  "<%= (@users.first.name) %><br>"
)
  • 以上でAjax通信を行い、viewの一部を更新するアプリが完成しました。
    • ユーザー一覧ページにある Run Ajax ボタンを押すと、画面に最初に登録したユーザーの名前がどんどん増えて行くと思います。
    • 本当は append() ではなく html() を使ったほうがいいのですが、見た目がわかりやすいので append() を使っています
    • Railsサーバーのログを見ながらボタンを押すと、ちゃんと裏で通信がされていることが分かるかと思います

作ったサンプルアプリ

サンプルアプリ

最後に

最低限動作するだけのサンプルなのでこのままでは使えませんが、RailsでAjaxがどのように使われているのかを見るのには役立ちそうです。
基本動作がわかったので、あとは実際のコードを追って動作を把握していきます。

JS側でAjax処理がされている場合もあるので、そちらの方もいつか書きたい。