5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Rails】Ajax通信でできること1(モーダルでデータを登録する編)

Last updated at Posted at 2023-11-06

どうもこんにちは。

今回は、RailsでのAjax通信について紹介をしようと思います。

ちなみに私は、Ajax通信のヘビーユーザーです。

Ajaxとは

Ajaxとは、「Asynchronous JavaScript + XML」の略。

つまり、「JavaScriptとXMLを使用したサーバとの非同期通信」のことです。

?????

同期通信と非同期通信

データ登録時の処理を例にして簡単に説明をすると、

同期通信は、

  1. アプリのページで登録ボタンを押す
  2. サーバーで登録処理を行う
  3. 処理が完了したら登録後のページに遷移できる

非同期通信は

  1. アプリのページで登録ボタンを押す
  2. サーバーでの登録処理をしている間に他のページに遷移できる

要するに、「直列動作」か「並列動作」かですね。

同期通信の例(通常の動作)

同期通信での詳細な動作は以下のようになります。

  1. アプリのページでフォームにデータを入力する
  2. アプリのページで登録ボタンを押す
  3. 登録ボタンを押されたことをトリガーにcreateメソッドが動作する
  4. createメソッドで登録処理が行われる
  5. 処理が完了したら登録後のページにリダイレクトする

実装は簡単で、以下のようなコードだけで足ります。

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通信の動作)

非同期通信での詳細な動作は以下のようになります。

  1. モーダルでフォームにデータを入力する
  2. モーダルで登録ボタンを押す
  3. 登録ボタンを押されたことをトリガーにjavascriptのクリックイベントが動作する
  4. javascript側で入力された情報を取得する
  5. javascript側からAjax通信によってcreate_ajaxメソッドが動作する
  6. create_ajaxメソッドで登録処理が行われる
  7. 登録処理が終わったら結果がjavascriptに戻ってくる
  8. 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とすることで非同期処理を行うこともできます。
こちらについては、ページの一部を動的に更新したい時に有効な方法なので、次の記事で紹介しています。

以上

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?