ブックマークボタンのAjax化

Ajax

ajax(Asynchronous Javascript and XML)とはjavascript,XML,DOMなどを組み合わせて非同期通信すること
同期通信では画面遷移に待ち時間があるが、非同期通信ではページの必要箇所だけ書き換えるので画面遷移がなく、スムーズな操作が行える。

実装内容

ブックマークボタン(☆★)の切り替えを画面遷移なしで実装していく。

ブックマークボタン☆★をそれぞれ非同期通信になるように設定する。

ブックマークリンクにremote:trueを追加。
link_toメソッドはデフォルトでは同期通信なのでremote: trueオプションを加えて非同期通信にする。
リクエストがhtml形式からjsへ変わり、js.erbファイルが出力されるようになる。

  <%= link_to bookmarks_path(board_id: board.id), 
  id: "js-bookmark-button-for-board-#{board.id}",
  class: 'float-right',  method: :post, remote: true do %>
  <%= icon 'far', 'star' %>
<% end %>

_unbookmark.html.erbにも同様に追加する。

<%= link_to bookmark_path(current_user.bookmarks.find_by(board_id: board.id)), 
  id: "js-bookmark-button-for-board-#{board.id}",
  class: 'float-right', method: :delete, remote: true do %>
  <%= icon 'fas', 'star' %>
<% end %>

jsファイルの作成

viewsにフォルダを作成する
views/コントローラ名/コントローラのアクション名.js.erb

  $("#js-bookmark-button-for-board-<%= @board.id %>").replaceWith("<%= j(render('boards/unbookmark',board: @board)) %>");

replaceWithメソッドで要素を置換している。
$(置換対象).replaceWith(置換後の要素)

$("#js-bookmark-button-for-board-<%= @board.id %>")_bookmark.html.erbのlink_toメソッドで指定してるidの要素(☆)であり、
これを("<%= j(render('boards/unbookmark',board: @board)) %>");に置換することで_unbookmark.html.erbをレンダーし★マークを画面遷移なしで表示させている。

    $("#js-bookmark-button-for-board-<%= @board.id %>").replaceWith("<%= j(render('boards/bookmark', board: @board)) %>");

$("#js-bookmark-button-for-board-<%= @board.id %>")は↑と同様。
これを("<%= j(render('boards/bookmark', board: @board)) %>");に置換することで_bookmark.html.erbをレンダーし☆マークを画面遷移なしで表示させている。

処理の流れ

同期通信
htmlリクエスト→bookmarks_controllerのcreate(destroy)アクション→データベース登録削除

非同期通信
jsリクエスト→bookmarks_controllerのcreate(destroy)アクション→create.js.erb(destroy.js.erb) →データベース登録削除

bookmarksコントローラの修正

画面遷移してしまうのでredirect_backを削除

  class BookmarksController < ApplicationController
  def create
    @board = Board.find(params[:board_id])
    current_user.bookmark(@board)
  end

  def destroy
    @board = current_user.bookmarks.find_by(params[:id]).board
    current_user.unbookmark(@board)
  end
end