使用環境
Ruby2.6.8
Rails6.1.4
非同期通信を用いることで、上の画像の♡を押すと、ページの更新なしに「いいね」をつけたり、消したりすることができます。
##処理の流れを説明する前に・・・
####前提
railsでjQueryを読み込めるようにする必要があります。
また、非同期通信でいいね機能を実装するためには、javascriptでHTML構造を書き換える必要があります。なので、それぞれの投稿を部分テンプレートで切り出す必要があります。
なので上の画像の水色で囲った部分は、javascriptで記述できるようにします。
以下に実際に実装したコードを例に説明していきます。
#処理の流れ
①「いいね」を送信(クリック)
②routeからコントローラに渡され、そこで「いいね」の保存、消去の処理
③「いいね」のデータをデータベースに格納
④ページの更新
##①「いいね」を送信(クリック)
まずは同期通信でいいね機能を実際に実装してみてください。
これが終わったらviewファイルを編集していきます。
いいね機能を実装していた箇所を以下のように変更してください。
<div id="likes_buttons_<%= @post.id %>">
<%= render partial: 'users/index',locals: {post: @post} %>
</div>
このrederでいいね機能の部分を読み取ります。
<% likes_count = Like.where(postId: post.id).count %>
<% if @current_user %>
<% if Like.find_by(postId: post.id,userId: @current_user.id) %>
<%= link_to "/likes/post/#{post.id}/delete",method: :post,remote: true do %>
<span class="fa fa-heart like-btn-unlike"></span>
<% end %>
<% else %>
<%= link_to "/likes/post/#{post.id}/create",method: :post, remote: true do %>
<span class="fa fa-heart like-btn"></span>
<% end %>
<% end %>
<%= likes_count %>
<% else %>
<%= link_to("/necessary_login", {class: "favo-button"}) do %>
<span class="fa fa-heart like-btn"></span>
<% end %>
<%= likes_count %>
<% end %>
上のファイル名の「_」はrenderで読み取る際には必須なので必ず忘れないように!!!
「_index.html.erb」のlink_toメソッドに注目してください。
「remote: true」と書かれているのが分かります。
(3つ目のlink_toはajaxしてませんが💦)
このremoteによってjavascript形式のリクエストを送信しているため、部分的な更新が可能となっています。
##②routeからコントローラに渡され、そこで「いいね」の保存、消去の処理 &「いいね」のデータをデータベースに格納
ここは同期通信の時とおおきくは変わらないです。
routeの設定をしてあげましょう。
post "/likes/post/:id/create" => "likes#create"
post "/likes/post/:id/delete" => "likes#delete"
これでルーティングが通りました。
ではこのルーティングをlikesコントローラで受け取り、処理を実行しましょう。
class LikesController < ApplicationController
def create
@post = Post.find(params[:id])
@like = Like.new(
postId: params[:id],
userId: @current_user.id
)
@like.save
end
def delete
@post = Post.find(params[:id])
@like = Like.find_by(
postId: params[:id],
userId: @current_user.id,
)
@like.destroy
end
end
これで、「いいね」の登録、削除の処理が完了しました。
同期通信の際には、redirectでページの更新を行っていたと思いますが、今回はajaxで行うので、redirectの部分がある人は消去しちゃってください。
##ページの更新
コントローラのcreate、deleteメソッドが行われた際に実行するjavascriptの処理を記述しましょう。
「views」配下に「likes/create.js」と「likes/delete.js」を作成してください。
そいてそれぞれに以下のような記述をしましょう。
$("#likes_buttons_<%= @post.id %>").html("<%= j(render partial: 'users/index',locals: {post: @post}) %>");
$('#likes_buttons_<%= @post.id %>').html("<%= j(render partial: 'users/index',locals: {post: @post}) %>");
これで、先ほど作成した「_index.html.erb」のrebder部分(いいね機能の部分)のHTML要素を更新することができました。
参考
https://qiita.com/naberina/items/c6b5c8d7756cb882fb20
https://techtechmedia.com/favorite-function-rails/