8
8

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 5 years have passed since last update.

[簡単!!!]誰でもできる「いいね👍」機能

Last updated at Posted at 2019-03-19

##はじめに
今回は前提としてUser, Postが既にあり、Likeを加えた3つのモデルでできるアプリとします。

1.Likesモデルの追加
2.アソシエーション
3.Likesコントローラの追加
4.Likesコントローラの設定
5.Postsコントローラの設定
6._like.html.erbの追加

##Likesモデルの追加

ターミナル
$ rails g model like post:references user:references
$ rails db:migrate

##アソシエーション

like.rb
class Like < ApplicationRecord
  belongs_to :user
  belongs_to :post 
end

post.rbの最後の行はlikesテーブルを中間テーブルとして経由してuserテーブルから情報を取ってくると言うことを表してます。
liked_usersにしていますが、ここはわかりやすい名前にして下さい。

post.rb
class Post < ApplicationRecord
  belongs_to :user
  has_many :likes
  has_many :liked_users, through: :likes, source: :user
end

post.rbと同様でlikesを経由してpostテーブルから情報を取ってきてliked_postsと言う名前で使用できます。

user.rb
class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
  has_many :posts, dependent: :destroy
  has_many :likes, dependent: :destroy
  has_many :liked_posts, through: :likes, source: :post

  #ユーザーが投稿に対して既にいいねしているか
  def already_liked?(post)
    likes.exists?(post_id: post.id)
  end
end

##Likesコントローラの追加

ターミナル
$ rails g controller likes

##Likesコントローラの設定

  1. create:
    ログインユーザーがあるpostに対してlikeする

  2. destroy:
    ログインユーザーがlikeしたpostを探して削除

  3. set_post:
    JSでなんとか出来るけどとりあえずいいねしたらredirectでpost#showへ遷移。
    しかし、今のままではlikes_controllerで@postは使えないのでprivate下で@postを定義する。

likes_controller.rb
class LikesController < ApplicationController
  before_action :set_post, only: [:create, :destroy]
  def create
    @like = current_user.likes.create(post_id: params[:post_id])
    redirect_to post_path(@post)
  end

  def destroy
    @like = Like.find_by(post_id: params[:post_id], user_id: current_user.id)
    @like.destroy
    redirect_to post_path(@post)
  end

  private
  def set_post
    @post = Post.find(params[:post_id])
  end
end

##Postsコントローラの設定
今回はPosts#showでいいね出来るようにするのでshowアクションに以下を付け加える。

posts_controller
def show
   @post = Post.find(params[:id])
   @comments = @post.comments.includes(:user)
--------↓これを加えてください-------
   @like = Like.new
end

##_like.html.erbの追加

**1行目:**user.rbで作った、記事に対していいねしているかどうかのメソッドです。

ログイン中のユーザーがあるpostにいいねしているのなら2~4行目の処理に行きます。

まだいいねしていないのなら6~8行目の処理に行きます。

**2~4行目:**いいね削除メソッドで、fontawesomeの❤️アイコンとdeleteメソッドをブロックを使って一体化しています。

またremote: trueを記述することで非同期でいいねすることができます。

**6~8行目:**いいねメソッドです。それ以外は2~4行目と同じです。

**10行目:**ある記事に対していいねされた数をカウントします。

_like.html.erb
<% if current_user.already_liked?(@post) %>
  <%= link_to post_like_path(@post), method: :delete, remote: true do %>
    <%= fa_icon 'heart', id: "heart__red" %>
  <% end %>
<% else %>
  <%= link_to post_likes_path(@post), method: :post, remote: true do %>
    <%= fa_icon 'heart', id: "heart__normal" %>
  <% end %>
<% end %>
<%= @post.liked_users.count %>

##最後は
部分テンプレートを使って_like.html.erbを呼び出します。

show.html.erb
<div class="post__like">
   <%= render 'likes/like' %>
</div>

##参考

Railsでいいね機能を実装しよう

【Rails】いいね機能の実装(.js.erbを用いない方法)【プログラミング学習165日目】

8
8
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
8
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?