RailsのフォームでのAjax通信について


はじめに

エンジニア1年生です。

日々の学びのメモとしてコツコツと記事を書こうと思っています。

今回はRailsでのAjax通信について書いていきます。


Ajaxとは?

Asynchronous JavaScript XMLを略したもので

Javascriptを使用してサーバーと非同期通信が出来る技術です。


非同期通信??

通常のweb通信は以下の流れとなります。

1、リンク等をクリック

2、ブラウザからサーバーにリクエストを投げる

3、サーバーからファイルがレスポンスが返される

4、ブラウザがファイルを読み込み画面が表示される

これが同期通信です。

上記の処理が行われる際はサーバーと通信中のため他の処理を行うことが出来ません、、、

サーバーと通信中でも他の処理を行うことが非同期通信です。

google mapやtwitterがページ遷移を行わずに快適に使用出来るのは非同期通信を行っているからです。


具体例

railsのフォームを使用して具体的な使い方を説明します。

例として好きな食べ物をフォームから送信し登録した際に別ページに遷移せず

アラートを表示するコードを書きます。


フォームの記述


food.html.erb

  <%= form_for(@food, data: { remote: true }) do |f| %>

<%= f.text_field :food %>
<%= f.submit('送信') %>
<% end %>

ポイントはremoto:trueを設定していることです。

formにremoto:trueを設定することにより画面遷移は行わずに

リクエストだけを投げてくれます。


コントローラーの記述


foods_controller.rb

def new

@food = Food.new
end

def create
@favorite_food = Food.new(food_form_params)

ActiveRecord::Base.transaction do
unless @favorite_food.save
raise ActiveRecord::Rollback
end
end

if @favorite_food.errors.any?
@errors = @favorite_food.errors.full_messages
render json: @errors, status: 422
else
render json: {}, status: 200
end
end

private
def food_form_params
params.require(:food).permit(:food)
end


ポイントはrender部分でjsonとstatusを返していることです

エラーの場合はjsonにエラーメッセージ、statusに422をセット

正常の場合はstatusに200をセット


jQueryの記述


food.js


$(function(){
$("#new_food").on("ajax:error", function(event, jqXHR, ajaxSettings, thrownError) {
var data = jqXHR.responseJSON;
alert(data);
});
});

$(function(){
$("#new_food").on("ajax:success", function(event, xhr, settings) { 
alert("登録が完了しました。");
});
});


ポイントはajax:error,ajax:successをトリガーに処理を記述していることです。

statusが200の場合は"ajax:success"、statusが422の場合は"ajax:error"が発火します。