【rails】いいね機能【初心者プログラミング】
railsでいいね機能を実装!!
前提
・ユーザー情報がある(Userモデルがある)
・投稿機能がある(今回は本の投稿機能(book)があります)
流れ
①モデル作成(Favorite)
②ルーティング
③アソシエーション
④コントローラ作成(favorites)
⑤ビュー
いいね機能の実装
①モデル作成(Favorite)
いいねの情報を保存するモデルを作成
$ rails g model Favorite
カラムを作成
class CreateFavorites < ActiveRecord::Migration[5.2]
def change
create_table :favorites do |t|
t.references :user, foreign_key:true
t.references :book, foreign_key:true
t.timestamps
end
end
end
reference型
外部キー制約をするために使用!
なぜ
→他のテーブルに格納されている値だけに限定することで親テーブルと子テーブルの整合性がとれる
references型を使うメリット
・userではなくuser_idというカラム名を作成してくれる
・インデックスを自動で貼ってくれる
※t.references :user だけでは外部キー制約はつかない
foreign_key:true を記述!
カラム名 | データ型 | カラムの説明 |
---|---|---|
id (自動生成) | integer | いいねごとのID |
user_id | integer(references) | いいねしたユーザのID |
book_id | integer(references) | いいねされた投稿画像のID |
テーブルを確定!
$ rails db:migrate
②ルーティング
ユーザーがURLにアクセスした時に、
どのコントローラのどのアクションに処理を振り分けるかを定義
Rails.application.routes.draw do
devise_for :users
root 'homes#top'
resources :users
resources :books do
resource :favorites, only: [:create, :destroy] //createとdestroyのみ使用
end
end
booksのルーティングにネストする
ネストすることで...
どの本に結びついたいいね(favorites)なのかURLで判断することが可能に!
$ rails routes 確認
book_favorites DELETE /books/:book_id/favorites(.:format) favorites#destroy
POST /books/:book_id/favorites(.:format) favorites#create
※このbook_idはparams[:book_id]で取得できる
③アソシエーション
関連する「favorite」「book」「user」のモデルファイルに関係性を記述
class Favorite < ApplicationRecord
belongs_to :user //1つのユーザーを持つ
belongs_to :book //1つの本を持つ
validates_uniqueness_of :book_id, scope: :user_id //1人1いいねのみ
end
validates
保存する時には、値が正しいかどうか確かめてくれる
「uniqueness」同一データは一つのみ許可する
class Book < ApplicationRecord
belongs_to :user //1つのユーザーを持つ
has_many :favorites,dependent: :destroy //複数のいいねを持つ
end
>dependent: :destroy
bookの情報が削除された時に結びついているいいねも削除される
class User < ApplicationRecord
has_many :books, dependent: :destroy //複数の本を持つ
has_many :favorites, dependent: :destroy //複数の本を持つ
//fovoritesの中にbook.idが存在する情報はあるか
def favorited_by?(book)
favorites.where(book_id: book.id).exists?
end
end
④コントローラ作成(favorites)
$ rails g controller Favorites
アクションを追加
(「いいねする」と「いいね外す」のみなのでcreate と destroyのみ)
class FavoritesController < ApplicationController
def create
//book_idを取得
book = Book.find(params[:book_id])
//現在のユーザーのいいねにbookのidを新しく入れる
favorite = current_user.favorites.new(book_id: book.id)
Favoriteテーブル | user_id | book_id |
---|---|---|
id (自動生成) | curent_user | book.id |
//favorite(表のデータ↑)を保存
favorite.save
//元のを再度読み込む→いいねされたページを開くことができる
redirect_back(fallback_location: root_path)
end
def destroy
book = Book.find(params[:book_id])
//現在のユーザーのいいねをbookのidから見つけ出す
favorite = current_user.favorites.find_by(book_id: book.id)
//bookを削除
favorite.destroy
redirect_back(fallback_location: root_path)
end
end
⑤ビュー
「いいなする」時と「いいね外す」時の画面表示を記述
//user.rbで定義した"favorited_by?(book)"で現在のユーザーがいいねしているか確認
<% if current_user.favorited_by?(recipe) %>
<%= link_to recipe_favorites_path(recipe),method: :delete do %>
♡
<% end %>
<% else%>
<%= link_to recipe_favorites_path(recipe),method: :post do %>
❤︎
<% end %>
<% end %>
<%= recipe.favorites.count %>