jQuery内からRailsのActionを叩く

  • 165
    いいね
  • 1
    コメント
この記事は最終更新日から1年以上が経過しています。

JQueryとの連携方法でいつもとまどう点をまとめとこう。というよりも、jQueryからRailsのアクションを呼ぶ方法。初心者にはなかなか流れが掴みにくいです。
用途は限定されるかもしれないですが、たとえばselectの変更をjQueryで検知したときに、RailsでActionを叩いてsessionの値を書き換えるときなどは次のようにする。

まず、流れ。
1)jQueryでselectの変更を検知する
2)jQuery内からURLを指定してAjax通信する
3)2)のURLがActionを叩くようにルーティングを設定する
4)2)のURLに従って、html.erbファイルを設置する
5)後は好きなようにAction内で処理をする

sample.html.erb
<select id="year_select" name="y" style="width:100px;">
    <option value="2011">2011</option>
    <option value="2012">2012</option>
    <option value="2013" selected="selected">2013</option>
    <option value="2014">2014</option>
</select>

例えば上のようなviewがあったとします。
#year_selectの変更を検知するjQueryが下記。

sample.js
$("select#year_select").change(function(){
        $.ajax({
            url: "projects/change_session_year",
            type: "GET",
            data: {year : $(":selected").attr("value"),
                    id: 1,
                    mode: 'hoge',
                    type: 'entry'
                    },
            dataType: "html",
            success: function(data) {
                alert("success");
            },
            error: function(data) {
                alert("errror");
            }
        });
    });

$.ajax はAjax通信するための構文。
url: 通信先のURLを指定。ルートからの指定でいいはず
data: 通信先に渡すパラメータ。Actionからはもちろんparams[]で取得できる
success,error 通信成功、失敗時の処理

慣れないとわかりにくいけど、通信後、戻り値がfunction(data)として渡されます。このdataをいじくってテンプレートを書き換えるというのが王道の使い方だと思いますが、ここではテンプレートはいじりません。

で、projects/change_session_year というURLでルーティングを設定します。

routes.rb
    get "projects/change_session_year"

次、要注意です。これを忘れたがために嵌って時間ロスるすことがよくあります。
ルーティングに対応するテンプレートファイルを設置する!この例であれば、

projects/change_session_year.html.erb を忘れずに設置してください!中身は空でいいと思います。

$.ajaxで通信した際、このテンプレートが無いとエラーが返ってしまいます。普通のRailsの処理であれば、恐らく、missing_tamplateエラーが出るのですぐにわかるんだけど、Ajaxの場合は何も言わず失敗するので、気づくのに時間がかかるんです。

後は、projectsコントローラーにchange_session_yearアクションメソッドを用意して、好きなように処理を入れればOKです。

projects_controller.rb
    def change_session_year
        session[:year] = 2013
    end

肝は4)のテンプレートを忘れないかどうか、じゃないでしょうか。