いいね機能(非同期通信)
Ajaxとは
「Asynchronous JavaScript + XML」の略(Asynchronous:非同期)。
HTMLリクエストでは画面全体の遷移によって更新を行っていますが、Javascriptリクエストを行うことでページの一部分だけを更新することが可能になります。今回はこのAjaxのしくみを使って具体的にどのように実装を進めて行くかを記述します。Javascriptと聞いて少しおよび腰になってしまいますが、私はJavascriptの知見はありませんでしたが実装できましたのでご安心下さい。
jQueryのインストール
gem 'jquery-rails'
JavascriptのライブラリであるjQueryをインストールします。
ターミナルでbundle installを忘れず行いましょう。
いいねボタンにAjaxを適応させる
<% if book.favorited_by?(current_user) %>
<%= link_to book_favorites_path(book), method: :delete, remote: true, style: "color: red;" do %>
<i class="fas fa-heart" aria-hidden="true"></i>
<%= book.favorites.count %>
<% end %>
<% else %>
<%= link_to book_favorites_path(book), method: :post, remote: true do %>
<i class="fas fa-heart" aria-hidden="true"></i>
<%= book.favorites.count %>
<% end %>
<% end %>
今回は、いいね機能を部分テンプレートに記述しています。
remote: true
でHTMLリクエストでなく、Javascriptリクエストがfavoritesコントローラーに送られます。
.
.
<tbody>
<% books.each do |book| %>
<tr>
<td><%= link_to(book.user) do %>
<%= image_tag book.user.get_profile_image, size:'50x50' %>
<% end %>
</td>
<td><%= link_to book.title,book %></td>
<td><%= book.body %></td>
<td id="favorite_btn_<%= book.id %>">
<%= render "favorites/btn", book: book %>
</td>
</tr>
<% end %>
</tbody>
.
.
<td id="favorite_btn_<%= book.id %>">
、後のjs.erbファイルの記述に更新したい箇所の指定が必要となるため、tdタグにHTMLのidで名前を付けます。
<h2>Book detail</h2>
<table class='table'>
・
・
・
<td id="favorite_btn_<%= @book.id %>">
<%= render "favorites/btn", book: @book %>
</td>
・
・
・
</table>
showページにも同様の記述をします。
リダイレクト先の削除
class FavoritesController < ApplicationController
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
end
リダイレクト先を削除&先述したremote: true
でJavascriptリクエストを行ったことにより、createアクション実行後は、create.js.erbファイルに、
destroyアクション実行後はdestroy.js.erbファイルに遷移します。
jsファイルの作成
$("#favorite_btn_<%= @book.id %>").html("<%= j(render 'favorites/btn', book: @book) %>");
$("#favorite_btn_<%= @book.id %>").html("<%= j(render 'favorites/btn', book: @book) %>");
所感
今日は<%= @book.id %>を<% @book.id %>(=抜け)したり、
bookを@bookにしなかったりで手こずりました。人の助けを借りながらエラー解決すると解決の道筋のたどり方が分かってすごく勉強になりますね!かっこよくエラー対応できるエンジニアになりたいものです。
Discussion