[ruby on rails]いいね機能つける→非同期通信にする

<h2>初めに</h2>
プログラミング学習初めて1ヶ月ほどです。
自身のアウトプット、不明点あらい出しのためにアウトプットしています。

＊まず最初に普通に「いいね」機能を作り、
その後、非同期通信にしています。

<h2>いいね機能つける not非同期通信</h2>
前回の記事でコメント機能をつけています。
本の投稿サイトに以下のようないいね機能をつけます。

```perl:routes.rb
resources:books,only:[:new,:create,:index,:show,:destroy,:edit,:update]do
    resource:favorites,only:[:create,:destroy]
    resources:book_comments,only:[:create,:destroy]
  end
```
<details><summary>resouceとresoucesの違い</summary><div>
以下の記事で理解できました。
favoriteのshowページを作成することもないですし、idの受け渡しが発生しないので、
resorceで記述します。

https://techtechmedia.com/resources-resource-difference/


</div></details>


<h2>テーブルとモデルの作成</h2>

必要なのは？？
１、いいね自体のid(integer型）
2、誰がいいねしたかのuser_id
３、どの投稿にいいねしたかの　book_id
2,3は外部キーですよね。

```
rails g model Favorite user_id:integer book_id:integer
```
```
rails db:migrate
```

<h2>アソシエーション</h2>

コメントの時と同様にアソシエーションを追記します。

```perl:user.rb
class User < ApplicationRecord
：
：
has_many :favorites, dependent: :destroy
：
```


```perl:book.rb
class Book < ApplicationRecord
  belongs_to:user

validates :title, presence: true
validates :body, presence: true,length:{maximum:200}
has_many :book_comments, dependent: :destroy
has_many :favorites, dependent: :destroy　　#追記


 def favorited_by?(user)
    favorites.where(user_id: user.id).exists?
 end　　#追記

end

```
<details><summary>　favorited_byってなに？whereってなに？？</summary><div>

まずwhere
モデル名.where(任意のカラム名: 格納されている値)となるそう。
既にいいね済みであれば、複数回いいねは出来ません

</div></detail>

```perl:favorite.rb
class Favorite < ApplicationRecord
  belongs_to:user
  belongs_to:book
end
```

<h2>コントローラー作成</h2>
```
rails g controller Favorites create destroy
```

<h2>Viewの作成</h2>
本の投稿一覧ページに以下の記載をします。

```
<% if @books.favorited_by?(current_user) %>

   <%= link_to book_favorites_path(@books), method: :delete do %>
   ♥<%= @books.favorites.count %>
   <% end %>

   <% else %>

    <%= link_to book_favorites_path(@books), method: :post do %>
     ♡<%= books.favorites.count %>
     <% end %>

  <% end %>
```

<h2>コントローラー記述</h2>

```
class FavoritesController < ApplicationController

  def create
    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])
    favorite = current_user.favorites.find_by(book_id: book.id)
    favorite.destroy
    redirect_to request.referer
  end

end
```

一行ずつ、解説？していきます。
<h6>Create</h6>
```book = Book.find(params[:book_id])```
まず、　「いいね」する本の投稿に紐付いているbook_idをparams:で取得します。

```favorite=current_user.favorites.new(book_id book.id)```
ここの記述は

<details><summary>コメント機能との違い</summary><div>
コメント機能ではdestroyで2つのidを取得していましたが、今回は１つしか取得していません・・・。
なぜかというと、resouceでルーティングを作成してるのでfavoriteコントローラーはidの受け渡しをやってくれていない　からだと思います。一方で、コメントのはresoucesで作成しており、book_commentのidとbookのidを両方取得していると。
</div></details>


<h2>出来上がりイメージ</h2>

![スクリーンショット 2021-07-06 9.58.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/c51ac333-4143-41ea-40fb-9123ddc2df72.png)

<h2>非同期通信にする</h2>
ここの記事がとても参考になります。
この通り行えば非同期通信ができます！


https://qiita.com/rised/items/6483257e61724480e5bc

<details><summary>非同期通信の簡単な流れ（個人メモ）</summary><div>
１、いいねのview部分を部分テンプレートにする
２、いいねを押す（外す）記述である<%= link_to〜の部分に、remote trueを加える　（非同期します！宣言）
3,コントローラーにあるredirect to~やらrender ~は消す！
２と３をやることで、次のリクエストがjsファイルに変わります。
それまでhtmlファイル探してたのが、「jsファイルどこ〜〜？」ってやってくれるようになる。
４、favoritesフォルダにアクション名と同じjsファイルを作成。必ずアクション名と一致させる！！



</div></details>

<h2>いいねの一覧表示</h2>
あるユーザーがいいねした記事の一覧表示の説明については以下で行っています。


https://qiita.com/ki_87/items/ba7de81d637aaf85e561