ブックマークボタンの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