※本サイトで紹介している商品・サービス等の外部リンクには、アフィリエイト広告が含まれる場合があります。
ユーザーが記事に「いいね」できるのは1回
- ユーザーは複数「いいね」する
- 記事は複数「いいね」される
でも、1人のユーザーが1つの記事に「いいね」できるのは1回である
config/routes.rbを開く
resources :articles do
resources :comments, only: [:new, :create]
resource :like, only: [:create]
end
resource :like
は単数形になる
記事のidが指定できればいい(:destroyで詳しく説明)
「いいね」して、likesテーブルにレコードを作る
→ create
(POSTリクエスト)になる
app/controllers/likes_controller.rbを作成する
ログインしていることを前提とする
class LikesController < ApplicationController
before_action :authenticate_user!
def create
article = Article.find(params[:article_id])
article.likes.create!(user_id: current_user.id)
redirect_to article_path(article)
end
end
↓ :article_id
が含まれているので、該当の記事をArticleから探してくる
article.likes.create
できる理由
→ article.rbにて、has_many :likes
を定義しているから.create
ができる- likesテーブルに必要なものは、
article_id
とuser_id
のみ
→user_id
はcurrent_user.id
だと渡してあげると、likesのレコードが作成できる - 「いいね」するだけなのに保存できなかった場合は絶対バグである
→create!
にしておけば、保存できないときはバグに気付ける - 「いいね」ができたら同じ画面
article_path
にredirect_to
する
保存するときに使うのはarticle_like_path(POST)
app/views/articles/show.html.hamlを開く
- if user_signed_in?
.article_heart
= link_to article_like_path(@article), data: { method: 'post' } do
= image_tag 'heart.svg'
- もしログインユーザーが「いいね」していたら?(
user_signed_in?
)
→ ’heart.svg’が表示される /articles/:article_id/like
に:article_id
が含まれている
→@article
をarticle_like_path
に渡すlink_to
はデフォルトが「GET」リクエスト
→ それ以外のときはdata: { method: 'post' }
のように書く
誰(ログインしている人)が、どの記事(@article)に「いいね」しているかが分かればいいので、コードはこれだけでok
コンソール画面を開く
User.first
User.first.likes
# => <Like id: 1, user_id: 1, article_id: 1, ...
Article.find(1)
Article.find(1).likes
# => <Like id: 1, user_id: 1, article_id: 1, ...
「いいね」できているので、Like id: 1が生まれている
下記のように画像を切り替えるようにする
- 「いいね」されていないとき→♡
- 「いいね」されているとき→♥
app/models/user.rbを開く
そのarticleは「いいね」されているか?has_liked?
def has_liked?(article)
likes.exists?(article_id: article.id)
end
likes
のうち、article_id
がarticle.id
と一致するlike
があるか?exists?
app/views/articles/show.html.hamlを開く
- if user_signed_in?
- if current_user.has_liked?(@article)
.article_heart
= image_tag 'heart-active.svg'
- else
.article_heart
= link_to article_like_path(@article), data: { method: 'post' } do
= image_tag 'heart.svg'
current_user
が「いいね」していたら(has_liked?
)、’heart-active.svg’を表示する- していなかったら、’heart.svg’を表示する
#DAY25