もふもふ技術部

Ruby on RailsでAjaxってどうやるん? 〜Redmineを読んでみる〜


環境

  • Mac OS X 10.7.5 Lion
  • ruby 1.9.3
  • Rails 3.2.12

コードを読む

WEB上にも情報はたくさんでているが、link_toのremote => trueってのが多い。これはJavaScriptの記述が最少になるので大変便利なんだが、実際にはselectタグとかinput textのonChangeでAjax発動したい場合がある。この辺のサンプルがあまり見当たらなかったので調べてみた。こういう場合は先達のソースコードを読むのもひとつの方法だ。今回はRuby on Railsで作られているプロジェクト管理システムのRedmineのソースコードを読んでみることにした。

Redmineのソースコードはgithubから入手できる。
https://github.com/redmine/redmine

解説的なアレ

まずはどこでAjaxをやってるか見つけなければならんわけだが、画面を動かして探してみてもこれが結構見つからない。埒があかないのでどうせjQueryだろうと踏んで”ajax”で検索してみる。予想通り色々見つかった。そのうちのひとつを追いかけてみる。

引数fieldIdで渡されたElementをjQueryオフジェクトにしてaddClassでスタイルを定義、Ajaxを発動するcheck関数をsetIntervalして300ミリ秒間隔で実行させる。といったところか。

check関数は、data-value-was属性の値と、対象のjQueryオブジェクトのvalue値を比較して、差異があればAjax発動と。

Ajaxの中身は、パラメータqに入力値をセットして引数urlにgetリクエストを投げる。通信に成功したら(success)引数targetIdをidに持つElementのjQueryオブジェクトのinnerHtmlに戻り値dataを入れこむ。通信開始前(beforeSend)にローディング状態を示すスタイルを定義。通信完了後(complete)にローディング状態のスタイルを破棄するといったような内容。

ではこれがどこで利用されているのか?部分テンプレートの_user.html.erbで呼び出されている。


rails_ajax_01

この部分テンプレートは 管理>グループ>ユーザータブ>新しいユーザー検索エリア で利用されている。表示しているグループに対してユーザーを追加したり削除したりする画面で、「ユーザーの検索:」テキストボックスの入力値でAjax検索されて該当ユーザーが表示される仕組みだ。上記observeSearchfield関数と照らしてみると、300ミリ秒間隔で入力値を監視して、入力値に変更があれば検索処理が走るという動きのようだ。

6行目でidが”user_search”のテキストフィールドを生成、7行目で上述のobserveSearchfield関数を呼ぶ。引数には検索フィールドのidである”user_search”、第二引数はnull、第三引数にgetリクエストを投げるパスを取得している(config/routes.rbに定義されているautocomplete_for_user_groupのパス)。

気になるのは第二引数のnull。上記のAjaxのsuccess時の処理対象idが渡されるはずでここがnullだと画面に処理結果が反映されないように見えるのだが、ちゃんと反映されている…。下記のようにコールバックを全てコメントアウトしても画面は正常に動いた。jQueryの仕様か?もう少し踏み込んでみないとわからないがこの辺はまたの機会としよう。

まとめ

RailsらしいAjaxの実装があるんじゃないのかな?と思って調べたのだが、ここで読んだのは割と従来と同じやり方で、あまり優位性があるものではなかった。ひょっとするとまだ他に方法があるようにも思えるが、ひとつの例として頭に入れておこう。付け加えて言うなら、副次的に、部分テンプレートやアプリケーション共通javascript(application.js)がどう使われているかを読むことが出来たので、そう意味では成果はあったということにしておこう。

The following two tabs change content below.
原田 敦

原田 敦

日本CAWのエンジニア。もふもふ部の部長。得意分野はRuby on Railsを使った小規模WEBアプリケーションを高速で開発すること。週末の楽しみは一人お菓子パーティー。三度の飯より小動物をもふもふするのが好きです。