#はじめに
現在オリジナルアプリの散歩習慣化アプリを製作中です。
以前の記事で、いいね機能の同期通信までをまとめたので、今回は同期通信までをまとめます!
前の記事です。
『rails』いいね機能の実装方法① 同期通信まで
https://qiita.com/yuhi_taka/items/47d8e50ea17b59f016c8
#前提と目標
・前提
前回までの「同期通信まで」で以下の状態まで実装できています。
同期通信で、いいねができるようになっています。
・目標
今回はいいね機能をjavascriptで非同期通信にして、画面をリロードすることなく、
いいねできるようにします。
※参考文献 ここからは以下の記事を参考にしました
https://techtechmedia.com/favorite-function-rails/
#部分テンプレートの切り出し
まずはそれぞれの投稿を部分テンプレートで切り出します。
↓↓renderでいいねを含めた投稿部分を切り出します。
<% @walks.each do |walk|%>
<%= render 'walk', walk: walk %>
<% end %>
↓↓「_walk.html.erb」と言うファイル名で、部分テンプレートを作ります。
<div class="col-mb-3" >
<div class="card ">
<%= link_to walk_path(walk) do%>
<%= image_tag walk.image, class: 'card-img-top px-3 mb-3' if walk.image.attached?%>
<div class="card-body">
<h5 class="card-title">今日の一言:<%= walk.content%></h5>
<p class="card-text">散歩時間:<%= walk.time%>分</p>
//ここよりいいね部分
<% if user_signed_in? && current_user.liked_by?(walk.id) %>
<%= link_to 'いいねを外す', walk_like_path(walk,walk.likes), method: :DELETE %>
<% else %>
<%= link_to 'いいね', walk_likes_path(walk,walk.likes), method: :POST %>
<% end %>
//ここまでいいね部分
</div>
<%end%>
</div>
</div>
ここまでで部分テンプレートの切り出しができました。
#remote: trueの付与
次にいいね部分のlink_to要素に、remote: trueを付与します。
「remote: true」を付与することで、パラメーターがHTML形式ではなくJS形式で送られるようになります。
こちらの記事で以下のように説明されています。
「remote: true」をlink_toメソッドに付与することで、likes_controller.rbのcreateアクション後は、views/likes/create.js.erbが呼び出されます。
<% if user_signed_in? && current_user.liked_by?(walk.id) %>
<%= link_to 'いいねを外す', walk_like_path(walk,walk.likes), method: :DELETE ,remote: true%>
<% else %>
<%= link_to 'いいね', walk_likes_path(walk,walk.likes), method: :POST ,remote: true%>
<% end %>
#redirect_toの削除
次にコントローラーのredirebt_toを削除して画面遷移を行わないようにします。
それでは実装してみます。
def create
like = Like.create(user_id: current_user.id,walk_id: params[:walk_id] )
redirect_to root_path
end
def destroy
Like.find_by(user_id: current_user.id,walk_id: params[:walk_id] ).destroy
redirect_to root_path
end
↓↓
def create
like = Like.create(user_id: current_user.id,walk_id: params[:walk_id] )
end
def destroy
Like.find_by(user_id: current_user.id,walk_id: params[:walk_id] ).destroy
end
#javascriptファイルの作成
次にjavascriptファイルを作成します。
views/likes 配下に
create.js.erbとdestroy.js.erbファイルをそれぞれ作ります。
それぞれ以下の記述をします。
document.getElementById('walk_<%= @walk.id %>').innerHTML = '<%= j(render @walk) %>'
document.getElementById('walk_<%= @walk.id %>').innerHTML = '<%= j(render @walk) %>'
そしてindexで部分テンプレート呼び出している箇所にIDを付与します。
<% @walks.each do |walk|%>
<%= render 'walk', walk: walk %>
<% end %>
↓↓
<% @walks.each do |walk|%>
<div id="walk_<%= walk.id %>">
<%= render 'walk', walk: walk %>
</div>
<% end %>
ここまででいいねの非同期処理は完成です。
#追加実装 アイコンをハート化
FontAwsomeを使っていいねボタンをハートマークにしました。
<% if user_signed_in? && current_user.liked_by?(walk.id) %>
<%= link_to walk_like_path(walk,walk.likes),class: "like-link",method: :delete, remote: true do %>
<i class="fa fa-heart unlike-btn mt-3"></i>
<% end %>
<% else %>
<%= link_to walk_likes_path(walk,walk.likes),class: "like-link",method: :post, remote: true do %>
<i class="fa fa-heart like-btn mt-3"></i>
<% end %>
<% end %>
FontAwsomeに関しては以下のサイトを参考にしました!
https://techtechmedia.com/font-awesome-rails6/
#まとめ
いいね機能の非同期通信の実装方法についてまとめました!
個人的には、javascript部分がまだ理解不足なのでさらに学習したいと思います。