JavaScript
Rails
Linux

railsとjsを使ったお手軽「いいね♡機能」

More than 1 year has passed since last update.


はじめに

プログラミング初心者の皆さんこんにちは!(こちらの記事はプログラミング初心者を対象に書いています。)

今回はjavascriptをあまり書いたことのない初心者の方でも簡単につくれるrailsとjavascriptを使った「いいね(like)機能」を実装していこうと思います。

基本的なrailsの説明は省いています。

今回はrailsのひとつ完成したアプリケーションがあるとしてそこに「いいね機能」を付け足すという流れで進めていきます。

今回は例として、ツイッターのようなSNSアプリに他人のツイートにいいねできるような機能を追加していこうと思います。

なのでtweet、userモデルとtweetsコントローラーがある前提で話を進めていきます。

一つのツイートに対して一人のユーザーがいいねできるのは一回までで、ツイッターのように灰色のハートを押すといいね(createアクション)、既にいいねされている赤のハートを押すといいねを取り消すこと(destroyアクション)ができます。


likesテーブルを作成しよう

ターミナルでlikesテーブルを作成しましょう。カラムはinteger型でuser_idとtweet_idを追加しておきましょう。

モデルファイルに以下を記述。


models/like.rb

class Like < ActiveRecord::Base

belongs_to :tweet, counter_cache: :likes_count
belongs_to :user
end

counter_cahce: :likes_countはリレーションされているlikeの数の値をリレーション先のlikes_countというカラムの値に入れますよって意味です。なのでlikes_countカラムをtweetsテーブルに追加しましょう。


tweetsテーブルにlikes_countカラムを追加しよう

tweetsテーブルにinteger型のlikes_countというカラムを追加しましょう。

さらに同モデルファイルに以下の記述を追加しましょう。


tweet.rb

class Tweet < ActiveRecord::Base

has_many :likes, dependent: :destroy
def like_user(user_id)
likes.find_by(user_id: user_id)
end
end

like_userメソッドは後に取り扱いますが、端的にいうとそのユーザーが既にツイートにいいねしているかどうか確認するメソッドです。


ルーティングを記述しよう

tweetsとlikesはネスト構造をとっています。resourcesを使いながら記述しましょう。


routes.rb

Rails.application.routes.draw do

resources :tweets do
resources :likes, only: [:create, :destroy]
end
end


アクションを定義しましょう

まずはlikes controllerを作成しましょう。作成したらそのファイルに以下を記述しましょう


likes_controller.rb

class LikesController < ApplicationController

def create
@like = Like.create(user_id: current_user.id, tweet_id: params[:tweet_id])
@likes = Like.where(tweet_id: params[:tweet_id])
@tweets = Tweet.all
end

def destroy
like = Like.find_by(user_id: current_user.id, tweet_id: params[:tweet_id])
like.destroy
@likes = Like.where(tweet_id: params[:tweet_id])
@tweets = Tweet.all
end
end


いいね(like)を増やすcreateアクションもdestroyアクションも同じで増やすたり消したりするlikeとそのあとの合計いいね数を表示するための@likes、とその後、tweetの一覧ページを表示するための@tweetsが定義されています。(ここでは説明を簡潔にしたいので記述を最低限におさえています。)


部分テンプレートを作ろう

今回はいいねボタンを部分テンプレートを使って作ります。

ユーザーがサインインしていない状態では押しても何も反応しないハートを表示します。ユーザーがサインインしているときは先ほど定義したlike_userメソッドを使いながら、そのユーザーがツイートにいいねしているかどうか判断しながら、表示を切り分けます。

ちなみに先ほど、likesのモデルファイルでcounter_cacheの記述を書いているので、tweet.like_countとするだけでそのツイートに結びつくlike数が表示されます。

どちらのアクションのパスもremote: trueの記述をしてajaxを使いながらアクションを実行します。

icon_red_heard.svgがいいね後の赤いハート、

icon_heart.svgがいいね前の灰色のハートととしてます。


_like.html.erb

<% if user_signed_in? %>

<% if tweet.like_user(current_user.id) %>
<%= button_to tweet_like_path(like, tweet_id: tweet.id), method: :delete, id: "like-button", remote: true do %>
<%= image_tag("icon_red_heart.svg") %>
<span>
<%= tweet.like_count %>
</span>
<% end %>
<% else %>
<%= button_to tweet_likes_path(tweet), id: "like-button", remote: true do %>
<%= image_tag("icon_heart.svg") %>
<span>
<%= tweet.like_count %>
</span>
<% end %>
<% end %>
<% else %>
<% = image_tag("icon_heart.svg") %>
<span>
<%= tweet.like_count %>
</span>
<% end %>


JSファイルを作ろう

いよいよjsを書く時がやって来ました。

ajaxを使ったページ遷移をせずにいいねを増やしたり消したりするjavascriptファイルを作りましょう。


views/likes/create.js.erb

$("#like-buttons").html("<%= j(render partial: 'like', locals: { tweets: @tweets, likes: @likes, like: @like}) %>")



views/likes/destroy.js.erb

$("#like-buttons").html("<%= j(render partial: 'like', locals: { tweets: @tweets, likes: @likes }) %>");


以上です。なんとjsを書くのはたったこれだけなんですね。なので今回のいいね機能はrailsの基本を押さえている方なら、多分すぐ出来てしまいます。簡単かつ普通に動くので他にもやり方は色々ありますが、このやり方は特におすすめです。