LoginSignup
1
1

More than 1 year has passed since last update.

いいね機能実装 [Ruby on Rails]

Last updated at Posted at 2021-07-25

完成品

いいね機能1.gif

投稿にいいね機能を実装する。
テーブルは、Users,Booksに加えFavoritesを追加する。

実装の手順

①モデルの作成
②ルーティングを追加
③それぞれのモデルに関連付けを追加
④コントローラを作成
⑤Viewを作成する

①モデルの作成

terminal
$rails g model Favorite user_id:integer book_id:integer

user_id:userとの紐づけ
book_id:book投稿との紐づけ
integer:データ型の整数

②ルーティングを追加

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

favoritesのshowページが不要で、idの受け渡しも必要ないので、resourceとなっています。
今回は、resources :booksにネストします。
resources :booksの中にresource :favorites , only: [:create , :destroy]を入れるという意味です。
ネストする理由は、ルートパスにあります。

routes.rb
#ネストしない場合
resources :books 
resource :favorites , only: [:create , :destroy]

ネストしないとルートパスが、下図になります。実はこのままだと、どの投稿(book_id)にいいねを付けたか特定することができません。
3.png
ネストすることでルートパスが下図になります。投稿(book_id)を特定することができますね。
2.png

③それぞれのモデルに関連付けを追加

app/model/user.rb
has_many :favorites, dependent: :destroy
app/model/book.rb
has_many :favorites, dependent: :destroy
def favorited_by?(user)
   favorites.where(user_id: user.id).exists?
end
app/model/favorite.rb
belongs_to :user
belongs_to :book

アソリエーション
※ user : favorite = 1 : 多 
※ book : favorite = 1 : 多

1つのuserからみて、いいねは多数あるのでhas_many
1つのbook(投稿)からみて、いいねは多数あるのでhas_many
1つのいいねからみて、user・book(投稿)は1つしかないのでbelongs_to
has_manyの後にはdependent: :destroyを付けましょう。

favorited_by?メソッドを作成します。
このメソッドで、引数で渡されたユーザidがFavoritesテーブル内に存在(exists?)するかどうかを調べます。

④コントローラを作成

terminal
rails g controller Favorites
app/controllers/favorites_controller.rb
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
#必要に応じてインスタンス変数を付けましょう。(book => @book)

current_userはログイン中のユーザーです。
request.refererは、元のviewに戻ってきます。いいねをクリック→いいねされたviewに戻ります。
なぜparamsの中が:book_idなのか?恐らくusr_idと混同するからと推測

⑤Viewを作成する

terminal
#<% books.each do |book| %>
<% if book.favorited_by?(current_user) %>
  <%= link_to book_favorites_path(book), method: :delete do %>♥<%= book.favorites.count %>
  <% end %>
<% else %>
  <%= link_to book_favorites_path(book), method: :post do %>♡<%= book.favorites.count %>
  <% end %>
<% end %>
#<% end %>
#book/indexで投稿を全て表示しているので今回はインスタンス変数なし

<% if book.favorited_by?(current_user) %>
いいねがクリックされている状態と、されていない状態で表示を変えます。

<%= book.favorites.count %>
いいねされた数を表示しています。

以上で実装完了となります。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1