rails + jquery + ajax + json을 사용한 비동기 통신 처리 흐름에 대해

소개



rails + jquery + ajax + json을 사용하여 실시간으로 게시를 할 수 있도록했을 때 어떤 처리 흐름이 이루어지고 있는지 정리해 보았습니다. (create만으로, 갱신, 삭제의 설명은 생략한다고 합니다.스마트폰으로 보면 꽤 보기 어렵다고 생각합니다.)

완성형




이와 같이 페이지 전이 없이 데이타베이스에 투고 내용을 보존하면서, 투고를 추가(취득)하는 것을 비동기 통신이라고 합니다.

구현하는 방법?



rails에 건네주고 있던 투고 내용의 정보를 javascript에 어떻게 건네줄까?



rails로 정의한 변수를 JavaScript로 전달하려면 json 형식으로 변환하여 전달해야합니다.
(gon( 공식 github 페이지 ) 라고 하는 gem에서는 Rails 의 변수를 간단하게 javaScript 에 건네준다고 한다.)
그러나 이번에는 gem을 사용하지 않고 비동기 통신으로 투고를 할 수 있도록 합니다.

처리의 흐름에 대해서



view는 기술량이 많아 엉망이 되어 있으므로 생략해서 이미지로 설명합니다.

우선 라우팅


# getであること!
get 'comments/create_comment', to: 'comments#create_comment'

보기





js 파일


$(document).on('click', '.create_comment', function() {
    var content = $('#content_' + $(this).attr('id').replace('comment_submit_', '')).val();
// ----------------------------------------------------------------------------
    if(content == '') {
      alert('コメントを入力してください。');               // 投稿が空欄だった場合の振る舞い
      return false;    
// ----------------------------------------------------------------------------
    } else {
// ----------------------------------------------------------------------------
      $.ajax({
        url: '/comments/create_comment',
        data: { note_id: $('#note_id').val(),     // まずはここ!
                content: content                  // 何か投稿があった時の振る舞い
              },
        dataType: 'json'
      })
// ----------------------------------------------------------------------------
      .done(function(data) {
        var html = buildHTML(data);
        $('.comments').append(html);             // json形式で値を受け取った後の処理
        $('.content').val('');
      })
// ----------------------------------------------------------------------------
      .fail(function(data) {
        alert('エラーが発生しました。')               // 受け取り失敗の場合の処理
      });
// ----------------------------------------------------------------------------
    }
  });

우선 투고 내용을 기입해, view 이미지의 녹색의 「작성」버튼을 누를 때에 jQuery의 클릭 이벤트가 발화합니다.
$.ajax 이하의 기술에서는, 우선 그 투고의 내용을 지정한 URL에 data내의 정보와 함께 보냅니다(게다가 json 형식으로!).

컨트롤러


def create_comment
# ------------------------------------------------------------------------
  @note = Note.find(params[:note_id])
  @comment = comments.new(permit_params)         # データベース内の処理
  @comment.save
# ------------------------------------------------------------------------
# ------------------------------------------------------------------------
  respond_to do |format|
    format.html { redirect_to note_path(@note) }
    format.json                         # データベースの処理が終わったあとどうするのか
  end
# ------------------------------------------------------------------------
end

$.ajax 내의 data로 받은 값을 바탕으로 @note 를 찾아내어 @comment그리고 다음에 데이타베이스에 보존한 뒤 어떻게 하는지, 라고 합니다.
get 에서 create_comment.~~$.ajax 로 하는 지정이 있었으므로 html 파일을 참조하는 것이 아니라, json 형식의 파일을 참조하려고 합니다. 다음은 dataType 파일입니다.

create_comment.json.jbuilder 파일


json.note_id           @note.id
json.note_edit_user    @note.user.full_name
json.comment_id        @comment.id
json.comment_user_name @comment.reply_user.full_name
json.comment_date      @comment.created_at.strftime('%Y/%m/%d %H:%M')
json.content           @comment.content

create_comment.json.jbuilder 파일에서는 컨트롤러에서 받은 값을 모두 json 형식으로 하여 값을 받습니다. 예를 들어,
json.content @comment.content

이것은 자바 스크립트 측면에서
data {
  'content': '@commentの投稿内容(content)'
}

로 전달되므로 json 에서 javaScript에서 Rails 변수의 값을 검색할 수 있습니다.
그리고 마지막으로 방금전의 js 파일로 남아 있던 create_comment.json.jbuilder 이후의 처리가 이루어지게 됩니다.

js 파일 (아래 계속)


// ----------------------------------------------------------------------------
      .done(function(data) {
        var html = buildHTML(data);
        $('.comments').append(html);             // json形式で値を受け取った後の処理
        $('.content').val('');
      })
// ----------------------------------------------------------------------------
      .fail(function(data) {
        alert('エラーが発生しました。')               // 受け取り失敗の場合の処理
      });
// ----------------------------------------------------------------------------
    }
  });

Rails에서 변수를 받을 수 있었으므로 나머지는 게시 내용을 html에 꽂기만 하면 됩니다. data.content 내에 받은 변수를 포함합니다.
function buildHTML(data) {
    var comment_write_user = data.comment_user_name == data.note_edit_user ? 'editor-comment' : 'reply-user-comment'
    var html = `<div class="comment-container">
                  <div class=${ comment_write_user }>
                    <div class="comment-header">
                      <div class="user-info">
                        <i class="far fa-user"></i><span class="user-name">${ data.comment_user_name }</span><span class="post-time">${ data.comment_date }</span>
                      </div>
                      <span class="custom-btn">
                        <input class="comment_id" type="hidden" value=${ data.comment_id }>
                        <div class="i far fa-edit edit-btn"></div><div class="delete_comment i far fa-trash-alt delete-btn"></div>
                      </span>
                    </div>

                    <div class="comment comment-${ data.comment_id }">
                      <p>${ data.content }</p>
                    </div>

                    <div class="edit-comment edit-comment-${ data.comment_id }">
                      <textarea class="form-control content" placeholder="コメントを入力してください" id="content_${ data.comment_id }" name="content[${ data.content }]">
                      </textarea>
                      <div class="btn btn-success float-right update_comment" id="comment_submit_${ data.comment_id }">更新</div>
                      <div class="btn preview-btn">プレビュー</div>
                    </div>
                  </div>
                </div>`
    return html;
  }

그리고 실제로 view에 추가가 반영되어 완성입니다.

참고 사이트



Ajax를 사용하여 비동기 통신으로 채팅 메시지 보내기

좋은 웹페이지 즐겨찾기