【Ruby on Rails】Ajax에서 특정 요소 변경

소개



Rails의 Ajax를 사용하여 특정 요소를 편집하고 업데이트하는 방법을 설명합니다.
예에서 간단한 카테고리 목록 화면의 하나의 카테고리 이름을 업데이트하는 프로세스를 사용합니다.

버전


  • 루비 2.6.3
  • rails 5.2.1

  • 화면 개요



    다음과 같은 화면입니다.


    이 오른쪽에 있는 연필 마크의 편집 아이콘 버튼을 누르면 해당 행의 카테고리 이름이 양식으로 바뀝니다.


    카테고리 이름을 변경하고 '업데이트'를 누르면,


    변경된 범주 이름으로 데이터가 업데이트되고 표시가 비동기적으로 변경됩니다.
    예에서는 교통 → 교통비로 변경합니다.


    처리 개요


  • 요소에 Ajax에 대한 옵션 추가
    link_to에 remote: true 옵션을 붙입니다.
  • Ajax에 대한 라우팅 추가
  • 컨트롤러 또는 모델에서 객체 검색 또는 업데이트
  • 추가한 액션을 위한 JavaScript용의 view 파일을 준비해, 화면의 해당 요소를 변경하기 위한 JavaScript를 기재

  • 구현 전



    구현 전의 주요 코드 부분은 다음과 같습니다.

    app/controllers/categories_controller.rb
    def index
      @categories = Category.where(user: current_user).order(:created_at)
    end
    

    app/views/categories/index.html.erb
    <ul class="todo-list" id="own-categories">
      <% @categories.each do |category| %>
        <li id="category-list-id-<%= category.id %>">
          <%= render 'a_category_list', category: category %>    
        </li>
      <% end  %>
    </ul>
    

    app/views/categories/_a_category_list.html.erb
    <span class="handle ui-sortable-handle">
      <i class="fa fa-ellipsis-v"></i>
      <i class="fa fa-ellipsis-v"></i>
    </span>
    <span class="text"><%= category.name %></span>
    <%= category.common_mark %>
    <div class="tools">
      <%= link_to edit_category_path(category), class: "text-redpepper space-left" do %>
        <i class="fa fa-lg fa-edit"></i>
      <% end %>
      <%= category.common_btn %>
    </div>
    

    카테고리 이름을 편집하는 양식으로 변경하는 Ajax 처리 구현



    연필 마크의 편집 아이콘 버튼을 누르고, 카테고리명의 요소를 폼 요소로 변경하는 처리를 기재해 갑니다.
    ※주의: 설명하지 않는 class 속성이나 id 속성 등이 있습니다만, Ajax 처리와는 관계 없습니다.

    1. Ajax에 대한 옵션 추가



    편집 아이콘 버튼에 remote: true를 넣는다.

    app/views/categories/_a_category_list.html.erb
    <%= link_to edit_category_path(category), remote: true, class: "text-redpepper space-left" do %>
      <i class="fa fa-lg fa-edit"></i>
    <% end %>
    

    2. Ajax에 대한 라우팅 추가



    Ajax 할 때도 라우팅의 resources 메소드가 유연하게 대응해줍니다.
    여기에서는 edit 액션을 추가합니다.

    config/routes.rb
    resources :categories, only: [:index, :edit]
    

    3. 컨트롤러에서 객체 얻기



    app/controllers/categories_controller.rb
    def edit
      @category = Category.find(params[:id])
    end
    

    4. 추가한 액션을 위한 JavaScript용 view 파일을 준비하고 화면의 해당 요소를 변경하기 위한 JavaScript를 기재



    edit 액션이므로 app/views/categories/edit.js.erb 를 만듭니다.

    app/views/categories/edit.js.erb
    id = "<%= @category.id %>";
    target = document.querySelector(`#category-list-id-${id}`);
    html = "<%= j(render partial: 'form', locals: { category: @category }) %>";
    target.innerHTML = html;
    

    app/views/categories/_form.html.erb
    <%= form_with(model: category) do |form| %>
      <div class="row">
        <div class="col-xs-10">
          <div class="input-group input-group-sm">
            <%= form.text_field :name, value: category.name, required: true, class:"form-control", max: 15 %>
            <span class="input-group-btn">
              <%= form.submit submit_btn_letters, class: "btn btn-brown" %>
            </span>
          </div>
        </div>
        <div class="col-xs-1">
          <%= category.cancel_btn %>
        </div>
      </div>
    <% end %>
    

    이제 카테고리 이름을 편집하기 위한 양식을 볼 수 있습니다.


    카테고리 이름을 업데이트하는 Ajax 처리 구현



    편집 양식으로 변경할 수 있었으므로, 다음에, 변경하고 싶은 문자 「교통비」로 변경해,
    갱신 버튼을 누르고, 갱신 후의 카테고리명을 표시하는 처리를 기재해 갑니다.

    1. Ajax에 대한 옵션 추가



    form_with에 remote: true 옵션을 추가합니다.
    (명시적으로 기재하지 않아도 디폴트로 remote: true 는 되어 있다.)

    app/views/categories/_form.html.erb
    <%= form_with(model: category, remote: true) do |form| %>
      <!-- 省略 -->
    <% end %>
    

    2. Ajax에 대한 라우팅 추가



    update 액션 추가

    config/routes.rb
    resources :categories, only[:index, :edit, :update]
    

    3. 컨트롤러에서 객체 업데이트



    카테고리 이름을 '교통비'로 업데이트합니다.

    app/controllers/categories_controller.rb
    def update
      @category = Category.find(params[:id])
      @category.update(category_params)
    end
    
    private
    def category_params
      params.require(:category).permit(:name, :is_common)
    end
    

    4. 추가한 액션을 위한 JavaScript용 view 파일을 준비하고 화면의 해당 요소를 변경하기 위한 JavaScript를 기재



    편집 양식을 업데이트된 카테고리 이름으로 변경하는 작업을 수행합니다.
    update 액션이므로 app/views/categories/update.js.erb 를 작성합니다.

    app/views/categories/update.js.erb
    id = "<%= @category.id %>";
    target = document.querySelector(`#category-list-id-${id}`);
    html = "<%= j(render partial: 'categories/a_category_list', locals: { category: @category }) %>";
    target.innerHTML = html;
    

    이제 카테고리 이름을 비동기적으로 업데이트할 수 있었습니다.


    결론



    JavaScript로 Ajax 처리를 작성해도 좋지만 간단한 Ajax는 Rails이면 쉽게 할 수 있습니다.
    다만, 〇〇.js.erb 의 쓰는 방법은 버릇이 강하기 때문에 요주의입니다.

    좋은 웹페이지 즐겨찾기