『rails』いいね機能の実装方法② 非同期通信の実装

#はじめに
　現在オリジナルアプリの散歩習慣化アプリを製作中です。
以前の記事で、いいね機能の同期通信までをまとめたので、今回は同期通信までをまとめます！

前の記事です。
『rails』いいね機能の実装方法① 同期通信まで
https://qiita.com/yuhi_taka/items/47d8e50ea17b59f016c8

#前提と目標　
**・前提**
前回までの「同期通信まで」で以下の状態まで実装できています。
[![Image from Gyazo](https://i.gyazo.com/4f32c0931667c17c49b3b5298d8d9947.gif)](https://gyazo.com/4f32c0931667c17c49b3b5298d8d9947)

同期通信で、いいねができるようになっています。

データベース設計は以下のとおりです。
![morning-walk.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2378833/3ff33848-1115-b8a7-b4a2-6081753ed312.png)

**・目標**
今回はいいね機能をjavascriptで非同期通信にして、画面をリロードすることなく、
いいねできるようにします。

**※参考文献　ここからは以下の記事を参考にしました**
https://techtechmedia.com/favorite-function-rails/


#部分テンプレートの切り出し
　まずはそれぞれの投稿を部分テンプレートで切り出します。
↓↓renderでいいねを含めた投稿部分を切り出します。

```index.html
<% @walks.each do |walk|%> 
    <%= render 'walk', walk: walk %>
<% end %>
```

↓↓「_walk.html.erb」と言うファイル名で、部分テンプレートを作ります。

```_walk.html
  <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形式で送られるようになります。

[こちらの記事](https://techtechmedia.com/favorite-function-rails/)で以下のように説明されています。
>「remote: true」をlink_toメソッドに付与することで、likes_controller.rbのcreateアクション後は、views/likes/create.js.erbが呼び出されます。

```_walk.html
<% 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を削除して画面遷移を行わないようにします。
 
それでは実装してみます。

```likes.controller.rb
　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ファイルをそれぞれ作ります。
それぞれ以下の記述をします。

```create.js
document.getElementById('walk_<%= @walk.id %>').innerHTML = '<%= j(render @walk) %>'

```

```destroy.js
document.getElementById('walk_<%= @walk.id %>').innerHTML = '<%= j(render @walk) %>'

```

そしてindexで部分テンプレート呼び出している箇所にIDを付与します。

```index.html
<% @walks.each do |walk|%> 
    <%= render 'walk', walk: walk %>
<% end %>

     ↓↓
<% @walks.each do |walk|%> 
   <div id="walk_<%= walk.id %>">
    <%= render 'walk', walk: walk %>
   </div>
<% end %>

```

ここまででいいねの非同期処理は完成です。

[![Image from Gyazo](https://i.gyazo.com/ad10c51c576883c3728b9e5f8743915e.gif)](https://gyazo.com/ad10c51c576883c3728b9e5f8743915e)

#追加実装 アイコンをハート化　
FontAwsomeを使っていいねボタンをハートマークにしました。

```index.html
<% 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 %>  
```
[![Image from Gyazo](https://i.gyazo.com/5238213749746617b24bc2b841dc5d4b.png)](https://gyazo.com/5238213749746617b24bc2b841dc5d4b)

FontAwsomeに関しては以下のサイトを参考にしました！
https://techtechmedia.com/font-awesome-rails6/

#まとめ
　いいね機能の非同期通信の実装方法についてまとめました！
個人的には、javascript部分がまだ理解不足なのでさらに学習したいと思います。

**※参考文献↓↓**
https://techtechmedia.com/favorite-function-rails/