いいね機能を入れよう　rails中心

リレーション関係を確認しよう


![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1514036/3049a133-83b7-3821-17ad-1f578088156d.png)


#①モデル（テーブルを作成しよう）

```
rails g model favorite user_id:integer recipe_id:integer
```

#②マイグレートしてテーブルをデータベースに登録する。

```
rails db:migrate
```

#③アソシエーション（テーブル同士の関連付け）
上記の図の線を書いていこう

```:favorite.rb
class Favorite < ApplicationRecord
  #1人のユーザーに属している
  belongs_to :user
  #1人の投稿に属している
  belongs_to :book
  
  validates_uniqueness_of :book_id, scope: :user_id
  
end
```

```
class Book < ApplicationRecord
	belongs_to :user
	# 多くの良いねを受け取る可能性がある、記事の削除と同時に削除する（いいね）
	has_many :favorites, dependent: :destroy
	# コメントの追加、記事の削除と同時に削除する
	has_many :post_comments, dependent: :destroy


	validates :title, presence: true
	validates :body, presence: true, length: {maximum: 200}
end


```

```
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

 
  has_many :active_relationships, class_name: 'Follow', foreign_key: 'user_id'
  has_many :passive_relationships, class_name: 'Follow', foreign_key: 'target_user_id'
  has_many :followings, through: :active_relationships, source: :target_user
  has_many :followers, through: :passive_relationships, source: :user




  has_many :books, dependent: :destroy
  has_many :favorites, dependent: :destroy
  # コメントの追加、記事の削除と同時に削除する
	has_many :post_comments, dependent: :destroy
  attachment :profile_image, destroy: false

  validates :name, length: {maximum: 20, minimum: 2}, uniqueness: true
  validates :introduction, length: {maximum: 50}
  
  # いいねしたかの判定
  
  def already_favorited?(book)
    self.favorites.exists?(book_id: book.id)
  end
  
end
```



#コントローラーに記述する

```
class FavoritesController < ApplicationController
  
  def create
    @favorite = current_user.favorites.create(book_id: params[:book_id])
    # その場に遷移させる
    redirect_back(fallback_location: root_path)
  end
  
  def destroy
　　#主キーに対してのfind
    @book = Book.find(params[:book_id])
　　#↓現在のユーザーについているいいねのデータを取ってくる　主キー以外のレコードでのfind_byになる
    @favorite = current_user.favorites.find_by(book_id:@book.id)
    @favorite.destroy
    redirect_back(fallback_location: root_path)
  end
end
```


```
@favorite = current_user.favorites.create(book_id: params[:book_id])

```

・current_user.favorites.createの意味は現在のユーザーに基づいた良いねを作成するよという意味です。
・(book_id: params[:book_id])これは良いねをした記事はどれなのかを取ってくるもの

```
redirect_back(fallback_location: root_path)
```
・いいねをしたところのページにそのまま遷移するという意味

findのまとめ
・主キーに対応するレコードを取り出す
・主キーを複数指定することも可能
・主キーが１つでも見つからない場合ActiveRecord::RecordNotFound例外が発生する
・findで取得したオブジェクトのクラスはBook　

find_byのまとめ
・与えられた条件にマッチするレコードのうち最初のレコードだけを返す
・条件を複数指定することができる
・与えられた条件がない場合nilを返す
・find_byで取得したオブジェクトのクラスはBook

#いいねをしたかしてないかの判定

```user.rb
  #Bookというデータにいいねをした？
  def already_favorited?(book)
　#selfは現在のユーザーと同じ意味。現在のユーザーがいいねをした？というレコード(book.id)があるかどうかを確認している
    self.favorites.exists?(book_id: book.id)
  end
```

#ネストしよう

```routes.rb
  resources :books do
   resource :favorites, only: [:create, :destroy]
  end
```
  
#viewへ

```books.html.erb
<table class="table table-hover table-inverse">
              <thead>
                <tr>
                  <th></th>
                  <th>Title</th>
                  <th>Opinion</th>
                  <th colspan="3"></th>
                </tr>
              </thead>
                    <% @books.each do |book| %>
                  <tbody>
                    <td><%= link_to user_path(book.user.id) do %>
                    <%= attachment_image_tag book.user, :profile_image, :fill, 100, 100, format: 'jpeg', fallback: "no_image.jpg", size:'100x100'  %>
                    <% end %> </td>
  <td><%= link_to book.title,book_path(book,title:book.title)%></td>
                    <td><%= book.body %></td>
                    <td>

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```                      
#もし現在のユーザーが投稿にいいねをしていたら
<% if current_user.already_favorited?(book) %>
#book_favorites_path(book=book_id投稿したというレコードのこと)にリンク
して、methodでfavoriteにあるdestoroyアクションを作動することができる。
<%= link_to  book_favorites_path(book),method: :delete do %>
                       <i class="far fa-thumbs-up"></i>
                       <% end %>
                      <% else %>
                       <%= link_to  book_favorites_path(book),method: :post do%>
                       <i class="far fa-thumbs-up"></i>
                      <% end %>
                      <% end %>
＃いいねの数をカウントしてくれるメソッド.count
                      <%= book.favorites.count%>
                    </td>
                    <td>
                        <%= link_to "#{ book.post_comments.count} コメント", book_path(book.id) %></td>
                    <% end %>
                 </tbody>
            </table>

```