🍎
【Rails】いいね機能実装(同期)
- アプリケーション作成済
- 「Userモデル」「Bookモデル」「Favoriteモデル」を使用して実装
- 完成イメージ ↓
1.Favoriteモデル、favoritesテーブルを作成
いいね機能用にFavoriteモデルとfavoritesテーブルを作成
ターミナル
$ rails g model Favorite user_id:integer book_id:integer
実行結果として下記が表示されればOK!
ターミナル
Running via Spring preloader in process 14418
invoke active_record
create db/migrate/20230724124903_create_favorites.rb
create app/models/favorite.rb
invoke test_unit
create test/models/favorite_test.rb
create test/fixtures/favorites.yml
ターミナル
$ rails db:migrate
- ここまでで「Favoriteモデル」「favoritesテーブル」が生成された
- 「user_id:integer」「book_id:integer」=カラムを外部キーとして生成
2.アソシエーションを設定
- 1人のUserはいいねをたくさん持っている(複数の投稿にいいねをすることができる)
- 1つのbookはたくさんのUserからのいいねを持っている
・・・つまり、UserとBookは「 多:多 」の関係性であるため、「 1:N 」の関係性を作れるように「中間テーブル」を作成する必要がある。
中間テーブルとして「favoritesテーブル」を作成し、「user_id」と「book_id」を結びつける。
app/models/user.rb
class User < ApplicationRecord
:
:
has_many :books, dependent: :destroy
has_many :favorites, dependent: :destroy ←これを追記!
:
- 「dependent: :destroy」=対象のUserが削除されたら、関連するFavoriteも削除される
app/models/book.rb
class Book < ApplicationRecord
:
belongs_to :user
has_many :favorites, dependent: :destroy ←これを追記!
- 「dependent: :destroy」=対象のBookが削除されたら、関連するFavoriteも削除される
app/models/favorite.rb
class Favorite < ApplicationRecord
belongs_to :user
belongs_to :book
end
3.Bookモデルにメソッドを定義
app/models/book.rb
:
:
def favorited_by?(user)
favorites.exists?(user_id: user.id)
end
- favorited_by?メソッド=favoritesテーブルにuser_idが存在するか(exists?)を調べる
- 存在すればtrue、存在しなければfalseを返す
4.ルーティング設定
app/config/routes.rb
Rails.application.routes.draw do
:
:
resources :books, only: [:new, :create, :index, :show, :edit, :update, :destroy] do
resource :favorites, only: [:create, :destroy]
end
:
- Userがいいねしたのは、どの「本」なのか。がわかるように、booksコントローラーのルーティングにネストさせる
- createアクション(いいねをつける)、destroyアクション(いいねを削除)を記述
$ rails routesの結果
ターミナル
book_favorites DELETE /books/:book_id/favorites(.:format) favorites#destroy
POST /books/:book_id/favorites(.:format) favorites#create
- ルーティングに「:book_id」が含まれている!
resource(単数形)resources(複数形)の違いについて、まだよく理解できていないので勉強します…
5.コントローラー作成
いいね機能用にfavoritesコントローラーを作成
ターミナル
$ rails g controller favorites
ルーティングで設定したcreate、destroyアクションを記述
app/controllers/favorites_controller.rb
class FavoritesController < ApplicationController
def create
end
def destroy
end
end
6.アクションを実装
app/controllers/favorites_controller.rb
class FavoritesController < ApplicationController
def create
book = Book.find(params[:book_id]) #外部キーである「book_id」を取得
favorite = current_user.favorites.new(book_id: book.id) #ログインしているユーザーがいいねをした本のidを取得し、いいねをつける
favorite.save #いいねを保存
redirect_to request.referer #アクション実行後に同ページに遷移(ページは変わらない)
end
def destroy
book = Book.find(params[:book_id]) #外部キーである「book_id」を取得
favorite = current_user.favorites.find_by(book_id: book.id) #ログインしているユーザーがいいねをした本のidを取得
favorite.destroy #いいねを削除
redirect_to request.referer #アクション実行後に同ページに遷移(ページは変わらない)
end
end
7.ビューを作成
books/showページに実装
app/views/books/show.html.erb
<% 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 %>
- Bookモデルに記述したfavorited_by?メソッドに引数としてcurrent_userを渡す
- current_user(ログインしているユーザー=自分)が含まれている場合、destroyアクションが動く
- current_user(ログインしているユーザー=自分)が含まれていない場合、createアクションが動く
ここまでで、いいねが表示されるようになりました!
こちらの記事を参考にさせていただきました🙏
Discussion