はじめに
ブックマーク処理をAjax化する方法を見ていきます。
前提として以下の用語について軽く知識を得ておきましょう。
Ajaxとは
Ajaxとは、「Asynchronous JavaScript And XML」の頭文字を取った言葉で、Webブラウザ上で非同期通信を行い、ページの再読み込みなしにページを更新するためのJavaScriptのプログラミング手法です。
株式会社万葉「現場で使えるRuby on Rails5 速習実践ガイド」マイナビ出版、2018年、332項
Rails-ujsとは
Railsの一部のRESTfulな動作や非同期な処理などを実現するために、JavaScriptの送信に関する処理などが書かれたライブラリです。
例えば、Viewヘルパーの form_with ( form_for など)の remote: true オプションだったり、 link_to の method: :delete などのオプションを「それっぽく動くように」動作させられるようになります。
裏方としてRailsアプリケーションの動作を支えてくれていということです。
作業の流れ
- ブックマークボタンにAjaxでサーバにリクエストを送信する処理を追加
- ブックマークボタンの切り替え処理を行うjsファイルを用意
- ブックマークコントローラのリダイレクト先を修正
ブックマークボタンにAjaxでサーバにリクエストを送信する処理を追加
それぞれのブックマークボタンのリンクに、remote: true
オプションを追加します。
これでJS方式でサーバにリクエストを送信できるようになります。
<%= 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 %>
<%= 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 %>
今までとajax処理の違い
今まで
ブックマークボタンのlink_to
↓
HTML形式でリクエストが送信される
↓
bookmarksコントローラのcreate or destroy アクション
↓
DB操作
↓
リダイレクト
今までのページ遷移では、ブラウザはページ全体のHTMLをサーバから取得し、続いてそのHTMLが要求するアセットすべてをサーバから取得して、ページを組み立てます。
ページの一部分を消すだけでも、ページ遷移で実現するには、再表示のために同じ過程をたどる必要があります。
Ajax
ブックマークボタンのlink_to
↓
JSリクエスト送信
↓
bookmarksコントローラのcreate or destroy アクション
↓
DB操作
↓
対象のjs.erbファイルを探して処理を実行
Ajaxを使うと、ページの一部だけをサーバから非同期でバックグラウンド上で取得、更新することが可能になり、HTML方式のページ遷移に比べて処理待ちストレスが無くなり、スムーズになります。
ブックマークボタンの切り替え処理を行うjsファイルを用意
$("#js-bookmark-button-for-board-<%= @board.id %>").replaceWith("<%= j(render('boards/unbookmark', board: @board)) %>");
$("#js-bookmark-button-for-board-<%= @board.id %>").replaceWith("<%= j(render('boards/bookmark', board: @board)) %>");
コードを紐解く
repraceWith()とhtml()の違い
html()
は指定したタグの中身をhtmlタグ付きで変えることができますが、指定したタグ自体は変わりません。よって今回のケースの場合、<a>タグの中にネストしたような形で表示されることになりました。

replaceWith()
は指定したタグの中身をhtml付きで変えることができます。更に指定したタグ自体も変えてしまします。今回の場合、replaceWith()
を使うことによってネストされずキレイに表示させることができました。

※ちなみに当方はreplaceWith
を replacewith
としていた為に、debuggerでデバッグするまで見つけられず、時間を取られました。
j() とは?
j()
は escape_javascript
のエイリアスです。
javascriptは""
や ''
があると正しく動かないみたいなので、それらをエスケープするためにも付ける必要があります。
ブックマークコントローラのリダイレクト先を修正
ajaxで処理を行うので、必要ない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
board
をビューファイル(create.js.erbとdestroy.js.erb)に渡すため、インスタンス変数にします。
終わりに
Ajax化はアプリケーション開発のさまざまなケースで用いられ得る手法ですのでしっかり抑えておきましょう。
参考記事


コメント