はじめに
先日、開発したサイト資格試験の質問サイト Qua(よくわからない人は以下のリンクを見てね!
rails歴10ヶ月の人が初めてWEBアプリを公開してみた)にいいね機能をつけました。簡単だろうと思っていたけど意外に手こずったところがあったので軽い説明とともに記事に残そうと思います。あと書いている私自身も初心者なので間違っている部分、もっといい方法がある場合はコメントに書いてくれると嬉しいです。
前提
初心者向け
投稿モデルはQuestionモデル
ユーザーモデルはUser.rb
がある前提です。
likeモデルを作る
投稿データを紐付けるlike_idと投稿した人のデータを登録するliker_idを作る。(わかりにくいので別の名前がいいかもしれない。)
rails g model like like_id:integer liker_id:integer
#カラムをもう少し違う名前にしたほうがわかりやすいかもしれない。
class CreateLikes < ActiveRecord::Migration[6.0]
def change
create_table :likes do |t|
t.integer :like_id
t.integer :liker_id
t.timestamps
end
end
end
↑こんな感じになったはず。
そしたらuserモデルに
has_many :likes
と書く。
アクションを作ろう
rails g controller likes
class LikesController < ApplicationController
def create
@like = Like.new(like_id: params[:like_id], liker_id: current_user.id )
@like.save
@question = Question.find_by(id: @like.like_id)
@likes = Like.where(like_id: @question.id)
end
def destroy
@like = Like.find_by(like_id: params[:like_id], liker_id: current_user.id)
@question = Question.find_by(id: @like.like_id)
@like.destroy
@likes = Like.where(like_id: @question.id)
end
end
簡単に説明するとcreateアクションの一行目で投稿と紐付けるlike_idといいねしたユーザーを認識するためのliker_idを登録する。
三行目で投稿データのIDを取得して四行目の@likesでいいね数をカウントする。
destroyはその名の通りcreateで作ったデータを消す。
単純っちゃ単純なしくみ。
テンプレートを作る
_like.html.erbという名前でテンプレートを作る。
<div class="like_button">
<% if current_user.likes.find_by(like_id: @question.id) %>
<%= link_to "いいね済み", {controller: :likes, action: :destroy, like_id: @question.id}, method: :delete, remote: true %>
<% else %>
<%= link_to "いいね", {controller: :likes, action: :create, like_id: @question.id}, method: :post, remote: true %>
<% end %>
<%= @likes.count %>
</div>
二行目でユーザーがいいねしているかどうか判別しtrueなら「いいね済み」,falseなら新しく「いいね」できるボタンを表示。
jsを書く
非同期通信をするためjsを書きます。
create.js.erbとdestroy.js.erbを新しく作り、
$(".like_button").html("<%= j(render("likes/like")) %>");
$(".like_button").html("<%= j(render("likes/like")) %>");
この一行だけで非同期通信ができるようになります。めちゃめちゃ簡単で短く楽ですね。
routes.rb
post "likes/:like_id", to: "likes#create"
delete "likes/:like_id", to: "likes#destroy"
これだけです。当たり前ですがデータの製作と削除をするだけなのでgetやpatchはいりません。
あとはいいね機能を実装したいページにrenderを書くだけです。
<% if user_signed_in? %>
<%= render "likes/like" %>
<% end %>
登録されていない人に押されるとエラーになるため一行目で登録していない人はボタンが表示されないようにしています。
おわり
お疲れさまでした!うまくいいね機能は実装できましたか?僕はいいね機能は結構難しいと思っていたのですが意外に仕組みは簡単なんだなと思いました。最後にここまで読んでくれてありがとうございました。(´ω`)