《Ruby on Rails》超簡単にいいね機能を実装する方法を発見!!


はじめに

いいね機能を色々調べてみましたが、
簡単な機能の割に物凄くややこしく複雑なコードと量で非常に効率が悪いようやきがしていて、もっとシンプルで簡単な方法を探してました。
おそらくこのやり方が1番シンプルなやり方だと思い、共有したく投稿しました。
参考になれば幸いです!!

環境

Ruby 2.5.1
Rails 5.2.4.5
MySQL
Cloud9

前提

投稿をpostで定義済。
deviseインストール済。

目的

Twitterの様に全ての投稿に対しいいね機能を付けたい!

①モデルの生成

$rails g model like user_id:integer post_id:integer

↑モデル名はlikeでカラムをuser_idとpost_idで作成。

rails db:migrate

↑データベースへ反映。

②アソシエーションを定義

user.rb
has_many :likes

↑userテーブルとlikeテーブルとは1対多の関係なのでhas_manyでアソシエーションを定義。

post.rb
has_many :likes

↑postテーブルとlikeテーブルとは1対多の関係なのでhas_manyでアソシエーションを定義。

like.rb
belongs_to :user
belongs_to :post

↑likeテーブルとuserテーブル、postテーブルとは多対1の関係なのでbelongs_toでアソシエーションを定義。

③userモデルにlike_by?メソッドを定義

user.rb
def liked_by?(post_id)
  likes.where(post_id: post_id).exists?
end

↑テーブルに関するメソッドはモデルに記載。
(テーブル内にpost_idが存在しているのかを検索し、最後のexists?であればtrue、なければfalseを判断。)

④コントローラの生成しメソッドを定義

$rails g controller likes
likes_controller.rb
def create
    Like.create(user_id: current_user.id, post_id: params[:id])
    redirect_to request.referer
end

def destroy
    Like.find_by(user_id: current_user.id, post_id: params[:id]).destroy
    redirect_to request.referer
end

↑いいねを押した時はcreate、いいねをやめる時はdestroyで定義し、redirect_to request.refererで元のページに遷移させてます。
(find_byは該当するレコードの複数のカラムを取得できる)

⑤ルーティングの設定

routes.rb
post 'like/:id' => 'likes#create', as: 'create_like'
delete 'like/:id' => 'likes#destroy', as: 'destroy_like'

↑いいねした時はpost、いいねをやめる時はdeleteで定義します。

⑥最後はビューに反映

index.html.erb
<% if current_user.liked_by?(post.id) %>
  <td><%= link_to 'いいね済', destroy_like_path(post), method: :DELETE %> <%= post.likes.count %></td>
<% else %>
  <td><%= link_to 'いいね', create_like_path(post), method: :POST %> <%= post.likes.count %></td>
<% end %>

↑countでいいねといいね済の横にいいね数を表示させてます。

以下の様に表示されるはずです!
【いいね前】

【いいね後】

あとは、CSSでデザインを変えれば完成です!!

最後に

プログラミングを勉強し始めてまだ間もないですが、挫折禁止を掲げ今も頑張ってます!
これからも挫折せず感化し合える仲間を増やして技術を共有できたらなと思います!
今回も色々と参考にさせて頂きました!先人は偉大なり!
この投稿で参考になれば幸いです!!ありがとうございました!!
これからも宜しくお願い致します^ ^