Rails3の form_for で Ajax をやってみた
一番シンプルっぽいパターンをメモ。とりあえず Ajax通信できた、というレベル。
通常の Ajax通信ではコールバックを html か js ファイルに書くと思っていたが、Rails3ではコントローラ側で js を生成してレスポンスを返すイメージらしい。
index.html.erb
- @tunes.each のループの中で form_for を使用しており、第一引数に tuneオブジェクトを設定している
- Ajax なので :remote => true とする
- フォームは簡単にテキストフィールドのみ。初期値を設定しつつ、リターンで変更後の値を Ajax通信として送信する
- レスポンスを "result" のタグに差し込む
<div id="result"></div> <table class="tunes"> <% @tunes.each do |tune| %> <tr> <td><%= link_to tune.name, tune %></td> <td><%= tune.tuning %></td> <td><%= tune.album %></td> <td> <%= form_for tune , :url => {:action => "update_progress", :id => tune.id }, :remote => true do |form| %> <%= form.text_field :progress %> <% end %> </td> </tr> <% end %> </table>
コントローラ
- コントローラ側に Ajax 通信を受け取る action の "update_progress" を追加
- Tune のデータベースを更新し、レスポンスで返す javascriptで使用する @name @updated_progress をメンバにしておく
- render を呼ぶことで対応する js.erb の "update_progress.js.erb" がレスポンスとして返る
def update_progress @tune = Tune.find(params[:id]) @name = @tune.name @updated_progress = params[:tune][:progress].to_i @tune.update_attribute(:progress, @updated_progress) render end
update_progress.js.erb
- レスポンスとして html上の "result" タグに更新された曲名と進捗率を表示する javascript を表示
$("result").update("updated_progress [<%= @name %>] : <%= @updated_progress %>%");
出来てしまえば簡単だけど、この方式を理解するのにすごく時間がかかった‥。きっとコントローラで js を生成しなくても、従来のように html または js 側で:success コールバックを登録する書き方もあるのかもしれない。jQuery なら見つけられた(参考2)が、prototype版も調べてみよう。