🐣
[Ruby on Rails] いいね機能の作成
テーブルの設計
いいね機能のテーブルは以下のようにします。
カラム名 | データ型 | カラムの説明 |
---|---|---|
user_id | integer | 「いいね」したユーザーのid |
book_id | integer | 「いいね」された投稿のid |
モデルの作成
$ rail g model Favorite user_id:integer book_id:integer
これでモデルは完成です。
モデルの関連付けを行う
book.rb
has_many :favorites, dependent: :destroy
user.rb
has_msny :favorites, dependent: :destroy
bookモデルにfavorited_by?メソッドを作成する
book.rb
def favorited_by?(user)
favorites.exists?(user_id: user.id)
end
- exists?メソッドは存在するかどうかを true と false で返すメソッド
- 今回は favoritesテーブルに 因数で渡された userの id が存在するかを返す
ルーティング
routes.rb
resources :books, only: [:index,:show,:edit,:create,:destroy,:update] do
resource :favorites, only: [:create, :destroy] #ここから追加
end
- 親の resource の中に do と end を使用して、子の resource を書くことを
ネストする
と言う - ネストしたURLを作ることで、
params[:book_id]
で Bookのidを取得できるようになる - いいね機能は 「一人のユーザーは一つの投稿に対して一回しかいいねが出来ない」 使用にため、 resource と単数系にすることで、 /:id が URLに含まれなくなる
- resource は「それ自身の id がわからなくても、関連するモデルの id から特定できる」 といった場合に使用する
コントローラー
いいね機能のcontrollerを作成します。
いいね機能ではviewを表示する必要がないです
$ rails g controller favorites
いいね機能には create と destroyアクションが必要になるので定義します
favorites_controller.rb
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.find(params[:book_id])
- find メソッドで Bookモデルから いいねされた投稿の id をもらう
favorite = current_user.favorites.new(book_id: @book.id)
- current_user.favorites は current_user に関連付けられた Favoriteモデルのいいねを指す
- favorites.new は空のインスタンスを作成している
- book_id: @book.id は作成されるいいねが指定される Bookのオブジェクトに関連付けをしている
favorite.save
- いいねしたことを保存している
redirect_to request.referer
- リクエストを行ったページに移動します。つまり同じページに戻るという意味です。
favorite = current_user.favorites.find_by(book_id: @book.id)
- find_by は()の中の条件に合う最初のレコードを一つだけ返すメソッドです。
- なので今回はログインしているユーザーはBookオブジェクトに関連付けられた favorite は存在するかを返します 見つからなかった場合 nil を返します
view
今回は部分テンプレートにいいね機能を書きます
_btn.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 %>
if book.favorited_by?(current_user)
- ログインしているユーザーはいいねをしているか? という意味
link_to book_favorites_path(book), method: :delete do
- link_to のオプションで、do から end までのオブジェクトにメソッドを指定して、リンクをつけます。
book.favorites.count
- 何個いいねがあるかを数えます。
部分テンプレートなので、showページなどの書くときは以下のようにして使用します。
books_controller.rb
@book = Book.new
books/show.html.erb
<%= render "favorites/btn", book: @book %>
こちらの記事を参考にさせていただきました。
Discussion