LoginSignup
0
3

More than 3 years have passed since last update.

今更だけどrails6でいいね機能を作ってみた! [非同期通信,ajax,js]

Last updated at Posted at 2020-04-22

はじめに

先日、開発したサイト資格試験の質問サイト Qua(よくわからない人は以下のリンクを見てね!
rails歴10ヶ月の人が初めてWEBアプリを公開してみた)にいいね機能をつけました。簡単だろうと思っていたけど意外に手こずったところがあったので軽い説明とともに記事に残そうと思います。あと書いている私自身も初心者なので間違っている部分、もっといい方法がある場合はコメントに書いてくれると嬉しいです。

前提

初心者向け
投稿モデルはQuestionモデル
ユーザーモデルはUser.rb
がある前提です。

likeモデルを作る

投稿データを紐付けるlike_idと投稿した人のデータを登録するliker_idを作る。(わかりにくいので別の名前がいいかもしれない。)

ターミナル
rails g model like like_id:integer liker_id:integer 
#カラムをもう少し違う名前にしたほうがわかりやすいかもしれない。
db/migrate/xxx_create_likes.rb
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モデルに

user.rb
has_many :likes

と書く。

アクションを作ろう

ターミナル
rails g controller likes
likescontroller.rb
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という名前でテンプレートを作る。

views/likes/_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を新しく作り、

views/likes/create.js.erb
$(".like_button").html("<%= j(render("likes/like")) %>");
views/likes/destroy.js.erb
$(".like_button").html("<%= j(render("likes/like")) %>");

この一行だけで非同期通信ができるようになります。めちゃめちゃ簡単で短く楽ですね。

routes.rb

config/routes.rb
  post "likes/:like_id", to: "likes#create"
  delete "likes/:like_id", to: "likes#destroy"

これだけです。当たり前ですがデータの製作と削除をするだけなのでgetやpatchはいりません。
あとはいいね機能を実装したいページにrenderを書くだけです。

好きなところ(僕の場合はshow.html.erb)
<% if user_signed_in? %>
<%= render "likes/like" %>
<% end %>

登録されていない人に押されるとエラーになるため一行目で登録していない人はボタンが表示されないようにしています。

おわり

お疲れさまでした!うまくいいね機能は実装できましたか?僕はいいね機能は結構難しいと思っていたのですが意外に仕組みは簡単なんだなと思いました。最後にここまで読んでくれてありがとうございました。(´ω`)

0
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
0
3