どうもこんにちは。
今回は、RailsでのAjax通信について紹介をしようと思います。
ちなみに私は、Ajax通信のヘビーユーザーです。
Ajaxとは
Ajaxとは、「Asynchronous JavaScript + XML」の略。
つまり、「JavaScriptとXMLを使用したサーバとの非同期通信」のことです。
?????
同期通信と非同期通信
データ登録時の処理を例にして簡単に説明をすると、
同期通信は、
- アプリのページで登録ボタンを押す
- サーバーで登録処理を行う
- 処理が完了したら登録後のページに遷移できる
非同期通信は
- アプリのページで登録ボタンを押す
- サーバーでの登録処理をしている間に他のページに遷移できる
要するに、「直列動作」か「並列動作」かですね。
同期通信の例(通常の動作)
同期通信での詳細な動作は以下のようになります。
- アプリのページでフォームにデータを入力する
- アプリのページで登録ボタンを押す
- 登録ボタンを押されたことをトリガーにcreateメソッドが動作する
- createメソッドで登録処理が行われる
- 処理が完了したら登録後のページにリダイレクトする
実装は簡単で、以下のようなコードだけで足ります。
html
<%= form_for @sample_normal, url: sample_normals_path(@sample_normal) do |f| %>
<%= f.label :sample_normals, :title %>
<%= f.text_field :title, autocomplete: "off", class: 'form-control col-sm-10' %>
<%= f.submit %>
<% end %>
controller
def create
@sample_normal = SampleNormal.new(sample_normal_params)
if @sample_normal.save
redirect_to sample_normals_path
else
render :new
end
end
private
# ストロングパラメータ
def sample_normal_params
params.require(:sample_normal).permit(:title)
end
非同期通信の例(Ajax通信の動作)
非同期通信での詳細な動作は以下のようになります。
- モーダルでフォームにデータを入力する
- モーダルで登録ボタンを押す
- 登録ボタンを押されたことをトリガーにjavascriptのクリックイベントが動作する
- javascript側で入力された情報を取得する
- javascript側からAjax通信によってcreate_ajaxメソッドが動作する
- create_ajaxメソッドで登録処理が行われる
- 登録処理が終わったら結果がjavascriptに戻ってくる
- javascript側からモーダルを閉じる
実装は同期処理よりも少し手間です。
html
<div id="sample_ajax_modal" class="modal fade show" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" style="display: none;" aria-modal="true" data-toggle="modal">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">タイトル追加</h4>
<button type="button" class="closeModal close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div class="modal-body p-4">
<div class="row">
<div class="col-md-12">
<div class="form-group row">
<div class="col-sm-2">
<label class="control-label">タイトル</label>
</div>
<div class="col-sm-10">
<%= text_field_tag 'sample_ajax_title', "", class: 'form-control' %>
</div>
</div>
</div>
</div>
<button type="button" id="create_title" class="btn btn-success waves-effect waves-light pull-right ml-2 mt-2">追加</button>
<button type="button" class="closeModal btn btn-light waves-effect waves-light pull-right ml-2 mt-2">キャンセル</button>
</div>
</div>
</div>
</div>
javascript
document.addEventListener('DOMContentLoaded', function() {
// ボタンを押された時のクリックイベント
document.getElementById('create_title').addEventListener('click', function() {
// テキストフィールドからタイトルを取得します
var title = document.getElementById('sample_ajax_title').value;
// Ajax通信を開始します
fetch('/sample_ajax/create_ajax', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
// RailsのCSRFトークンを設定します
'X-CSRF-Token': document.querySelector('[name="csrf-token"]').content
},
body: JSON.stringify({ title: title })
})
.then(response => response.json())
.then(data => {
console.log(data);
})
.catch(error => {
console.error('Error:', error);
});
# モーダルを閉じる
$('#sample_ajax_modal').modal('hide');
});
});
controller
def create_ajax
sample_ajax = SampleAjax.new(title: params[:title])
respond_to do |format|
if sample_ajax.save
format.json { render json: 'save ok' }
else
format.json { render json: 'save fail' }
end
end
end
上記のように入力フォームをモーダルで表示することによって、いちいち新規登録画面や編集画面に遷移しなくてもデータの登録、編集ができるようになります。
(編集の場合は、既存のデータをモーダルに表示する必要があるのでモーダルを開く際にもAjax通信を行う必要があります。)
実装は少々手間に感じるかもしれないですが、自分でデータの流れを確認しながら実装できるので、繰り返し実装していけばすぐに理解できます。
まとめ
今回はAjax通信についてまとめてみました。
Javascriptを使用することによって、非同期処理を実現することができました。
ただし、JavaScriptを使用するときはRails側でファイルパスが通っているか確認をしてください。
app/javascripts
ディレクトリに存在しているapplication.js
に直接処理を書いても良いですが、基本的には同じディレクトリにモデル名と同じ名前のjsファイルを作成して、application.js
にはimport '作成したjsファイルの相対パス'
を記述した方がよろしいかと思われます。
他にも普段使用しているhtml.erbファイルをjs.erbとすることで非同期処理を行うこともできます。
こちらについては、ページの一部を動的に更新したい時に有効な方法なので、次の記事で紹介しています。
以上