はじめに
今回は、オリジナルアプリに実装した「いいね機能」について
振り返りながら記事を書きたいと思います。
オリジナルアプリでいいね機能は2箇所実装しました。
1.投稿に対するいいね
2.コメントに対するいいね
この2つです。
別テーブルで作成しました。
今回は、コメントに対するいいね機能の記事を書きたいと思います。
なお、ユーザー管理機能、投稿機能、コメント機能は実装済みです。
1.テーブル設計
2.モデル作成(テーブル作成、バリデーション、アソシエーション)
3.ルーティング設定
4.コントローラー設定
5.ビューの設定
バージョン
・Ruby 2.6.5
・Rails 6.0.0
テーブル設計
・likesテーブル
Column | Type | Options |
---|---|---|
user | references | null: false, foreign_key: true |
post | references | null: false, foreign_key: true |
comment | references | null: false, foreign_key: true |
Association
- belongs_to :user
- belongs_to :post
- belongs_to :comment
user、post、commentは紐づいているので、references型でオプションでforeign_key: true
をつけています。
commentにいいねしたい場合、投稿も紐づいているためpostカラムも必要になります。
どのユーザーがどの投稿のどのコメントにいいねをしたのかわかるようにしてます。
アソシエーションはユーザー、投稿、コメントは1に対してlikeは多の関係になります。
モデルの作成
テーブル設計ができましたら、次にモデルを作成します。
% rails g model like
モデルを作成したら、マイグレーションファイルに記述します。
2021xxxxxxx_create_likes.rb
class CreateLikes < ActiveRecord::Migration[6.0]
def change
create_table :likes do |t|
t.references :user, null: false, foreign_key: true
t.references :post, null: false, foreign_key: true
t.references :comment, null: false, foreign_key: true
t.timestamps
end
end
end
先ほどのテーブルのカラムを記述したら、
% rails db:migrate
マイグレーションを行いテーブルを作成完了です!!
次にモデルにアソシエーションとバリデーションの記述を行います。
models/like.rb
class Like < ApplicationRecord
belongs_to :user
belongs_to :post
belongs_to :comment
validates_uniqueness_of :comment_id, scope: :user_id
end
ここでのバリデーションは、1つのコメントに対して1度しかいいねできないように
組んでいます。
ここにコードは載せませんが、User、Post、Commentのモデルに
has_many:likesの記述を行っています。
ルーティングの設定
routes.rb
Rails.application.routes.draw do
devise_for :users
root to: 'posts#index'
resources :users, only: [:show, :edit, :update, :destroy]
resources :posts do
resources :comments, only: :create do
resources :likes, only: [:create, :destroy]
end
end
end
ここで、ルーティングをネストさせます。
まず、postsコントローラー(親)→commentsコントローラー(子)の関係性があります。
そこに、commentsコントローラー(親)→likesコントローラー(子)の関係性でネストさせます。
ネストをさせる理由は、アソシエーション先のレコードのidをparamsに追加してコントローラーに送るためです。
今回だと、いいねに結びつくコメント投稿のidをparamsに追加します。
これで、ターミナルでルーティングを確認する。
% rails routes
コントローラーの設定
まずは、コントローラーを作成します。
% rails g controller likes
次にコントローラーにコードを記述します。
controllers/likes_controller.rb
class LikesController < ApplicationController
def create
post = Post.find(params[:post_id])
comment = Comment.find(params[:comment_id])
@like = Like.create(user_id: current_user.id, post_id: post.id, comment_id: comment.id)
redirect_to post_path(comment.post)
end
def destroy
post = Post.find(params[:post_id])
comment = Comment.find(params[:comment_id])
Like.find_by(user_id: current_user.id, post_id: post.id, comment_id: comment.id).destroy
redirect_to post_path(comment.post)
end
end
ここでは、いいねの保存と削除のアクションを記述しています。
createアクション
post = Post.find(params[:post_id])
comment = Comment.find(params[:comment_id])
いいねされたコメントに紐づく投稿を変数postに格納する。
いいねされたコメントのidとPostテーブルのidが一致するものをfindで見つけて変数postに格納。
@like = Like.create(user_id: current_user.id, post_id: post.id, comment_id: comment.id)
こちらでいいねを保存する処理を記述します。
destroyアクション
def destroy
post = Post.find(params[:post_id])
comment = Comment.find(params[:comment_id])
Like.find_by(user_id: current_user.id, post_id: post.id, comment_id: comment.id).destroy
redirect_to post_path(comment.post)
end
find_byメソッドを使用して、それぞれのidが一致したいいねを取り消す処理を記述します。
viewの記述
最後にviewの記述を行います。
views/likes/_like.html.erb
<%if user_signed_in? %>
<% if Like.find_by(user_id: current_user.id, post_id: @post.id, comment_id: comment.id) %>
<%= link_to post_comment_like_path(@post, comment, comment.likes), {class: "like-link", method: :delete } do %>
<i class="fas fa-grin-squint-tears unlike-btn"></i>
<% end %>
<p class="count"><%= comment.likes.count %></p>
<% else %>
<%= link_to post_comment_likes_path(@post, comment), {class: "like-link", method: :post } do %>
<i class="far fa-grin-squint-tears like-btn"></i>
<% end %>
<p class="count"><%= comment.likes.count %></p>
<% end %>
<% else %>
<i class="fas fa-grin-squint-tears unlike-btn"></i><p class="count"><%= comment.likes.count %></p>
<% end %>
user_signed_in?メソッドを使用しログインしていないユーザーには、カウント数だけ表示
されるようにしています。
そして、if文でfind_byメソッドを使用し、idが一致したものがあれば、削除のボタンを表示し、
一致しない時は、いいねボタンが表示されるようにしています。
以上がいいね機能実装の手順になります。
初心者の私にはかなり難しく感じました。
実装できたものの、理解できていない部分もあります。
もし何か間違いや聞きたいことがありましたら、コメント
していただければ幸いです。