リレーション関係を確認しよう
#①モデル(テーブルを作成しよう)
rails g model favorite user_id:integer recipe_id:integer
#②マイグレートしてテーブルをデータベースに登録する。
rails db:migrate
#③アソシエーション(テーブル同士の関連付け)
上記の図の線を書いていこう
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のまとめ
・主キーに対応するレコードを取り出す
・主キーを複数指定することも可能
・主キーが1つでも見つからない場合ActiveRecord::RecordNotFound例外が発生する
・findで取得したオブジェクトのクラスはBook
find_byのまとめ
・与えられた条件にマッチするレコードのうち最初のレコードだけを返す
・条件を複数指定することができる
・与えられた条件がない場合nilを返す
・find_byで取得したオブジェクトのクラスはBook
#いいねをしたかしてないかの判定
#Bookというデータにいいねをした?
def already_favorited?(book)
#selfは現在のユーザーと同じ意味。現在のユーザーがいいねをした?というレコード(book.id)があるかどうかを確認している
self.favorites.exists?(book_id: book.id)
end
#ネストしよう
resources :books do
resource :favorites, only: [:create, :destroy]
end
#viewへ
<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 %>
<% end %>
<% else %>
<%= link_to book_favorites_path(book),method: :post do%>
<% end %>
<% end %>
#いいねの数をカウントしてくれるメソッド.count
<%= book.favorites.count%>
<%= link_to "#{ book.post_comments.count} コメント", book_path(book.id) %>
<% end %>