いいね機能の非同期化

＃Bootstrap使用
**非同期化とは？**
・送信者のデータ送信タイミングと受信者のデータ受信タイミングを合わせずに通信を行う通信方式を指します。

・画面全体を更新せずに、一部だけ更新すること

**jQueryインストール**
``Gemfile``
```
gem "jquery-rails"
```
**インストール行う**
```
 $ bundle install
```
**部分テンプレートを作成**
どこに作成してもいいのですが、今回は、favoriteディレクトリに作成
`` favorite/_favorite-btn.html.erb``

 ``部分テンプレート_favorite-btn.html.erb``
```diff_ruby


<% if book.favorited_by?(current_user) %>
  <%= form_with(url: book_favorites_path(book), method: :delete, remote: true, class: "unlike-form", local: true) do |f| %>
    <%= f.button type: :submit, class: "unlike-btn" do %>
      <i class="fas fa-heart" style="color: red;"></i>
      <%= book.favorites.count %>
    <% end %>
  <% end %>
<% else %>
  <%= form_with(url: book_favorites_path(book), method: :post, remote: true, class: "like-form", local: true) do |f| %>
    <%= f.button type: :submit, class: "like-btn" do %>
      <i class="far fa-heart"></i>
      <%= book.favorites.count %>
    <% end %>
  <% end %>
<% end %>

```
`` favorites_controller``
:star:redirect_to request.refererを消す。
**createアクション**
対応するBookオブジェクトをデータベースから検索します。その後、ログインしているユーザーに関連付けられたFavoriteオブジェクトを作成し、そのお気に入りを保存します。
**destroyアクション**
対応するBookオブジェクトをデータベースから検索します。その後、ログインしているユーザーに関連付けられたお気に入りを検索し、該当するお気に入りを削除します。

```diff_ruby
class FavoritesController < ApplicationController
  def create
    @book = Book.find(params[:book_id])
    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])
    book = Book.find(params[:book_id])
    favorite = current_user.favorites.find_by(book_id: book.id)
    favorite.destroy
-redirect_to request.referer
  end
end
```

**各link_toにremote: trueを付け加えて非同期化する場合**
``_favorite-btn.html.erb``
```diff_ruby
<% if book.favorited_by?(current_user) %>
  <%= link_to book_favorites_path(book), method: :delete, remote: true do %>
    <i class="fas fa-heart" aria-hidden="true" style="color: red;"></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 %>
```
**form_withとlocal:falseで非同期化する場合**
＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿
:star:if文を使用して、bookが現在のユーザーによっていいねされているかどうかをチェックしています。
:star:book.favorited_by?(current_user)は、bookが現在のユーザーによっていいねされているかどうかを確認するメソッドです。
:star:いいねされている場合は、form_withを使用して削除のリクエストを送信するフォームを作成します。
フォームのurl属性にはbook_favorites_path(book)が設定され、method属性には:deleteが指定されます。また、local:falseを使用して非同期通信を有効にします。
:star:f.buttonメソッドを使用してボタンを作成し、いいねの数を表示します。
いいねされていない場合は、同様にform_withを使用して作成のリクエストを送信するフォームを作成します。
フォームのurl属性にはbook_favorites_path(book)が設定され、method属性には:postが指定されます。
また、CSSクラスを使用してボタンのスタイリングを行っています。
これにより、いいねボタンが表示され、非同期通信を使用していいねの追加や削除が行われるようになります。





```diff_ruby
<% if book.favorited_by?(current_user) %>
  <%= form_with(url: book_favorites_path(book), method: :delete, local:false, class: "unlike-form") do |f| %>
    <%= f.button type: :submit, class: "unlike-btn" do %>
      <i class="fas fa-heart" style="color: red;"></i>
      <%= book.favorites.count %>
    <% end %>
  <% end %>
<% else %>
  <%= form_with(url: book_favorites_path(book), method: :post, local:false, class: "like-form") do |f| %>
    <%= f.button type: :submit, class: "like-btn" do %>
      <i class="far fa-heart"></i>
      <%= book.favorites.count %>
    <% end %>
  <% end %>
<% end %>
```
``favorites``のディレクトリ内に
``create.js.erb``　と　``destroy.js.erb``を作成
（ファイル名はアクション名と同じものにします。）

``create.js.erb``&``destroy.js.erb``に以下を追加
```diff_ruby
$("#favorite_buttons_<%= @book.id %>").html("<%= j(render 'favorites/favorite-btn', book: @book) %>")
```
:star:**$("#favorite_buttons_<%= @book.id %>")**
は、お気に入りボタンを表示するためのコンテナです。
:star:**.html("<%= j(render 'favorites/favorite-btn', book: @book) %>")**
は、選択したHTML要素の中身を指定のコンテンツで置き換える操作を行います。具体的には、'favorites/favorite-btn'という部分テンプレートをレンダリングし、その結果をHTMLコンテンツとして設定します。この部分テンプレートは、いいねボタンを表示するためのHTMLを含んでいます。
:shamrock:したがって、この行のコードは、特定のHTML要素の中身をお気に入りボタンのHTMLに置き換えるという意味を持ちます。これにより、非同期通信の結果を反映して、お気に入りボタンが更新されます。

``_index.html.erb``
・いいねボタンを追加する。
:star:**id="favorite_buttons<%= book.id %>">**
は、特定の本のお気に入りボタンとお気に入り数を表示するHTMLテーブルセルです。
:star:**<%= render "favorites/favorite-btn", book: book %>**
は、favorites/favorite-btnという部分テンプレートをレンダリングして表示します。部分テンプレート内で、本のお気に入りボタンとお気に入り数が表示されます



```diff_ruby
 <td id="favorite_buttons_<%= book.id %>">
  <%= render "favorites/favorite-btn",book:book %> </td>
```
最後にbooks/index.html.erbにいいねボタンを追加するため_index.html.erbを呼び出す
（インスタンス変数@booksを定義）
``books/index.html.erb``
```
 <%= render 'index', books: @books %>