[Rails] Ajaxを使ったブックマークボタンの実装

学習記録

はじめに

ブックマーク処理を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>タグの中にネストしたような形で表示されることになりました。

https://i.gyazo.com/7ddf911d611ef9de3db02eb0c6291c62.png

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

https://i.gyazo.com/8665fd05276c7b6f11cf16ede31b777d.png

※ちなみに当方はreplaceWithreplacewith としていた為に、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化はアプリケーション開発のさまざまなケースで用いられ得る手法ですのでしっかり抑えておきましょう。

参考記事

初心者目線でAjaxの説明 - Qiita
AjaxとはAjaxとは「Asynchronous JavaScript + XML」の略Asynchronousとは、非同時性の、非同期のつまり、「JavaScriptとXMLを使って非同期…
replaceWith()の使い方〜jQuery
replaceWith()はある要素を指定されたHTMLやDOMエレメントで置き換えるものとリファレンスでは説明されていますが、少しわかりにくいので解説します。ざっくりとみると、html()と働きが似ています。html()は指定したタグの中

コメント

タイトルとURLをコピーしました