🐣
[Ruby on Rails] いいね機能の非同期通信
非同期通信とは
- ネットワークなどで繋がれているコンピューター間で、送信者のデータ送信タイミングと受信者のデータ受信タイミングを合わせずに通信を行う通信方法です。
- 同期通信はデータ通信のリクエストを出してからレスポンスが来るまで他の処理を行わないが、非同期通信ではレスポンスが来るまでに他の処理を行える。
Ajax とは?
- Ajaxとは、JavaScript でサーバー側との通信を「非同期」で行い、通信結果によって 「動的にページの一部だけ書き換える手法のこと」 です。
今回のいいね機能の非同期通信では、いいねボタンを押したら、リロードされずにいいねアイコンが変わるようにしたいので、 Ajax を使用します
gem の追加
Gemfile
gem 'jquery-rails'
gem を追加したら、インストールします
$ bundle install
いいねの view ページに Ajax の処理を追加
今回は 部分テンプレートにいいねの view ページを作成しています
favorites/_btn.html.erb
<% if book.favorited_by?(current_user) %>
<%= link_to book_favorites_path(book), method: :delete, remote: true do %>
❤<%= book.favorites.count %>
<% end %>
<% else %>
<%= link_to book_favorites_path(book), method: :post, remote: true do %>
♡<%= book.favorites.count %>
<% end %>
<% end %>
解説
- remote: true と書くことで、 Ajax 通信でリクエストを送信できる様になります
- Ajax 通信 簡単に言うと 部分的に通信ができる通信方法
今回は使用していませんが、普段はこちら
- Ajax 通信 簡単に言うと 部分的に通信ができる通信方法
- local: true こちらは HTML 通信でリクエストが送信されるようになります
- HTML 通信 簡単に言うと ページ全体をリロードして、通信する通信方法
index の View ページも変更
こちらも部分テンプレートに書いてあります
books/_index.html.erb
<table>
<% books.each do |book| %>
<td id="favorite_buttons_<%= book.id %>">
<%= render "favorites/btn", book: book %>
</td>
</table>
- id を使用して、更新したいところに名前をつけます
コントローラーの変更
favorites.controller
def create
@book = Book.find(params[:book_id])
favorite = current_user.favorites.new(book_id: @book.id)
favorite.save
# redirect_to request.referer
end
def destroy
@book = Book.find(params[:book_id])
favorite = current_user.favorites.find_by(book_id: @book.id)
favorite.destroy
# redirect_to request.referer
end
- この2箇所をコメントアウト、または削除します
- リダイレクト先を削除することで、 Ajax 通信と HTML 通信を混同させない様にします
- 結果 create アクション実行後は
create.js.erb
ファイルを
destroy アクション実行後はdestroy.js.erb
ファイルが実行されます
js.erb ファイル
まずは 以下のファイルを作成します
favorites/create.js.erb
favorites/destroy.js.erb
次に中身を記述します
favorites/create.js.erb
$('#favorite_buttons_<%= @book.id %>').html("<%= j(render "favorites/btn", book: @book) %>");
favorites/destroy.js.erb
$('#favorite_buttons_<%= @book.id %>').html("<%= j(render "favorites/btn", book: @book) %>");
プチ解説
-
(render で呼び出す際に書いた id 名).html( 部分テンプレートの呼び出し)
の形になっている - j は escape_javascript の略
- javascript の中で HTML を記述する際に実行結果を エスケープするためのメソッド
こちらの記事を参考にさせていただきました
Discussion