2
0

More than 3 years have passed since last update.

Railでの非同期通信(Ajax)を利用したいいね機能の実装

Posted at

使用環境
Ruby2.6.8
Rails6.1.4

完成イメージ

スクリーンショット (30).png

非同期通信を用いることで、上の画像の♡を押すと、ページの更新なしに「いいね」をつけたり、消したりすることができます。

処理の流れを説明する前に・・・

前提

railsでjQueryを読み込めるようにする必要があります。

また、非同期通信でいいね機能を実装するためには、javascriptでHTML構造を書き換える必要があります。なので、それぞれの投稿を部分テンプレートで切り出す必要があります。

スクリーンショット (30)_LI.jpg

なので上の画像の水色で囲った部分は、javascriptで記述できるようにします。

以下に実際に実装したコードを例に説明していきます。

処理の流れ

①「いいね」を送信(クリック)
②routeからコントローラに渡され、そこで「いいね」の保存、消去の処理
③「いいね」のデータをデータベースに格納
④ページの更新

①「いいね」を送信(クリック)

まずは同期通信でいいね機能を実際に実装してみてください。

これが終わったらviewファイルを編集していきます。
いいね機能を実装していた箇所を以下のように変更してください。

views/users/index.html.erb
<div id="likes_buttons_<%= @post.id %>">
    <%= render partial: 'users/index',locals: {post: @post} %>
</div>

このrederでいいね機能の部分を読み取ります。

views/users/_index.html.erb
<% 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の設定をしてあげましょう。

route.rb
post "/likes/post/:id/create" => "likes#create"
post "/likes/post/:id/delete" => "likes#delete"

これでルーティングが通りました。
ではこのルーティングをlikesコントローラで受け取り、処理を実行しましょう。

likes_controller.rb
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」を作成してください。
そいてそれぞれに以下のような記述をしましょう。

views/likes/create.js
$("#likes_buttons_<%= @post.id %>").html("<%= j(render partial: 'users/index',locals: {post: @post}) %>");
views/likes/delete.js
$('#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/

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0