3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

投稿に対していいね機能を実装する

Posted at

#概要
今回、twitterのような投稿アプリに対して
いいねを押したり、取り消したりできる機能と、
いいねをカウントして件数を表示できる機能と、
いいねするリンクをハートにする実装についてまとめておきます。

ちなみに、投稿にいいねをする機能に関しては、progateにカリキュラムがありますが、自分はそのまま実装しても思うような機能にならなかったので、qiitaをはじめとするサイトをたくさん検索しました。

それも踏まえてまとめようと思います。

#機能の見た目
like-qiita.png

#実装
####likeモデルを用意する

rails g model like

マイグレーションファイルに
t.references, foreign_key: trueとして、user_idとpost_idのカラムを設定します。

models/like.rb
class Like < ApplicationRecord
  validates :user_id, presence: true
  validates :post_id, presence: true
end

####ルーティングを設定する

routes.rb
post "likes/:post_id/create" => "likes#create"
post "likes/:post_id/destroy" => "likes#destroy"

これによってrails routesをすると次の画像のようになります。
これは、ビューファイルにリンクを指定するときに必要になるのであとで間違えないようにしましょう。

like-routes.png

####コントローラーを作成する

controllers/likes_controller.rb
class LikesController < ApplicationController
  before_action :authenticate_user!



  def create
    @like = Like.new(user_id: current_user.id, post_id: params[:post_id])
    @like.save
    redirect_to "/posts/#{@like.post_id}"
  end

  def destroy
    @like = Like.find_by(user_id: current_user.id, post_id: params[:post_id])
    @like.destroy
    redirect_to("/posts/#{params[:post_id]}")
  end


end

保存や削除をした後にその投稿の詳細ページにリダイレクトされるようになっています。

####ビューファイルを用意しよう

views/posts/show.html.erb
<div class="like-btn">
    <% if Like.find_by(user_id: @current_user.id, post_id: @post.id) %>

      <%=link_to("/likes/#{@post.id}/destroy", {method: :post}) do %>
        <span class="fa fa-heart like-btn-unlike"></span>
      <% end %>

    <% else %>

      <%= link_to("/likes/#{@post.id}/create", {method: :post}) do %>
        <span class="fa fa-heart like-btn"></span>
      <% end %>

    <% end %>
  </div>

まずは条件分岐でユーザーがいいねしているかしていないかを分岐し、
ボタンを押したときlikeをcreateするか、destroyするかを指定します。

そして、次に書きますが、link_to ~~~ doとする事で間にHTML文を挟むことができます。(理解が浅ければprogateのrailsカリキュラムを参照)

link_toのURLは間違えないようにしましょう。

先ほどルーティングでのせた画像の通り、/likes/post_id/create(またはdestroy)と記述します。

####いいねをハートアイコンのボタンにする

この部分はprogateを参考にしたのでこれ以外知らないんですけど、
font-awesomeというものを使って、いいねするリンクをボタンにしていきます。

まずはfont-awesomeを使えるようにhead部分にリンクを読み込みます。

views/layouts/application.html.erb
 ---省略---

  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
 </head>

ビューファイルはもう適した形式で記述しているので、
最後にいいねしていたらピンク、していなかったらグレーとなるようにcssを記述します。

先ほど記述したviews/posts/show.html.erbを確認すればわかりますが、いいねするボタンと取り消すボタンでlike-btnとlike-btn-unlikeが分かれています。

assets/stylesheets/likes.scss
.like-btn {
  color: #8899a6;
}


.like-btn-unlike {
  color: #ff2581;
}


.posts-show-item .fa {
  font-size: 16px;
  margin-right: 3px;
}

これでハートボタンでいいねしたり取り消したりすることが可能になっているはずです。

最後に、いいねの件数をカウントして表示しましょう。

####件数をカウントして表示する

postsコントローラーのshowメソッドに@like_countを定義してあげて、ビューファイルで表示するような手順になります。

controllers/posts_controller.rb
def show
    @post = Post.find(params[:id])
    @comment = Comment.new
    @comments = @post.comments.includes(:user)
    @like_count = Like.where(post_id: @post.id).count
 end

whereでその投稿についてるいいねをデータベースから検索して、countで数えていくように定義しています。

views/posts/show.html.erb
<div class="like-btn">

  <h3>いいね件数:<%= @like_count %></h3>

    <% if Like.find_by(user_id: @current_user.id, post_id: @post.id) %>
      <%=link_to("/likes/#{@post.id}/destroy", {method: :post}) do %>
---省略---

以上で完成です。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?