4
3

More than 3 years have passed since last update.

【Rails】Ajaxでいいねの数を表示する方法

Posted at

概要

前回の続きでいいねカウントの実装をしていいねの数を表示していきたいと思います。

APIの作成

まずJavaScriptからリクエストが来たときに返したいデータを定義していきます。
JavaScriptでリクエストを送ったら現在のいいね数をresponseで返すことができれば、実装できると思いました。

いいねの数を取得するために、LikesControllerのshowアクション内でlike_countを定義しました。

app/controllers/likes_controller.rb
def show
  like_count = @team.likes.count
  render json: { likeCount: like_count }
end

ただ、私が実装したいことは

現在のいいね数をDOMContentLoadedイベント時に取得することだけでなく、POSTとDELETEのリクエストの時にも取得したいと考えています。
そのため、showアクション内にだけ定義するのではなくcreate, destroyにも定義していく必要があります。createdestroyでもrender jsonlikeCountを入れないとJavaScriptからのリクエストに対応するデータがないのでundefinedになって返ってきてしまいます。

前回と重複するところもありますが、LikesControllerの記述はこのようになると思いました。before_action :like_countsでアクションの最初に読み込むようにしています。

LikesController

app/controllers/likes_controller.rb
class LikesController < ApplicationController
  before_action :authenticate_user!
  before_action :set_like
  before_action :like_counts

  def show
    like_status = current_user.has_liked?(@team)

    render json: { hasLiked: like_status, likeCount: like_counts }.to_json
  end

  def create
    @team.likes.create!(user_id: current_user.id)

    render json: { status: 'ok', likeCount: like_counts }.to_json
  end

  def destroy
    like = @team.likes.find_by!(user_id: current_user.id)
    like.destroy!

    render json: { status: 'ok', likeCount: like_counts }.to_json
  end

  private

  def set_like
    @team = Team.find(params[:team_id])
  end

  def like_counts
    @like_count = @team.likes.count
  end
end

どこにいいねの数を表示するのか

show.html.haml
.star_counter
  現在
  %span
  がいいねをしています。

今回、star_counterクラス内のspanタグ内にいいねの数を入れていこうかと思います。spanを入れた理由はいいねの数をscssでスタイルを調整しようと考えているからです。たとえば、以下のようにすればいいねの数だけ文字が赤く太くなります。

SCSS

scss
.star_counter {
  span {
    color: red; // 好きな色
    font-weight: bold; // 線を太くして強調
  }
}

いいねの数を取得(GET)

JavaScriptで実装したいこととしてはまず、GETリクエストで現在のいいねの数を取得することです。
そのため、GETリクエストが成功したらいいねの数を表示させていきます。

コードにするとこのようになると思いました。 ※前回と重複するところは省略しております。

jQuery
// GET, POST, DELETEリクエストで使うので処理をまとめています。
const likeCountCalculation = (likeCount) => {
// いいねの数を表示させたいところを取得。今回はstar_counterクラス内のspan要素を取得しています。その後appendで追加していくという処理です。
  $('.star_counter > span').append(
    `${likeCount}人`
  )
}

// axiosでGETリクエスト成功
.then((response) => {
// response内に先程Controllerで書いたlikeCountがjson形式で返されるので取得。
  const likeCount = response.data.likeCount
// 上で定義してあるlikeCountCalculation()が呼び出されて、span要素内に現在のいいねの数が表示されるようになります。現在のいいねの数はlikeCountに入っているので関数を呼び出すときにを引数にいれています。
  likeCountCalculation(likeCount)
})

いいねの数の増減 (POST, DELETE)

はじめは、likeのcountを+1, -1することで実装すればと思っていたのですが、それよりもGETの処理と同じ考え方で現在のいいねの数を取得すれば良いのでは?と考えました。現在のというのは+1や-1されたあとのいいねの数のことです。要するに、POSTやDELETEリクエストが成功すればいいねの数は増減しているのでその値を取得することで実装できると思いました。
コードにするとこのようになると思います。POSTもDELETEも同じ記述なのでまとめて書かせていただきます。GETの処理と違う点は、リクエストが成功したらspan要素の中身を空にするということです。これをしないとリクエストの度に要素が追加されていってしまいます。

jQuery
// axiosでリクエスト(POST or DELETE)成功
.then((response) => {
  // responseに入ってくるいいねの数を取得
  const likeCount = response.data.likeCount
  // star_counterクラス内のspan要素の中身を空にする。
  $('.star_counter > span').html('')
  // 現在いいねの数を表示する。
  likeCountCalculation(likeCount)
})

まとめ

  • 前回同様やりかたは一つではないこと。
  • 親要素内の子要素を取得する方法もひとつではなく選択肢がたくさんあり、わかりやすいものを使う。(読みやすいコードだったり状況に応じて判断)
  • jsonで複数の値を返すには記述を変える必要がある。

最後に

自分の実装したいことをどうやって実現していくのか、ここの言語化が大事だと感じました。実装したいことに対して、いくつもの方法があるということは、簡単に書けるものだったり逆に複雑になってしまったりすることがあると思います。こういったところもたくさんコードを書いたり技術書を読んだり、記事を見たりして学習していくことで力をつけていきます。

参考文献

前回書いた記事です。いいねの実装をこちらでしているのでよろしければご覧ください!
4
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
4
3