【Rails】総計いいね数表示の実装

# 実装すること

* ユーザーが得たいいねの数を合計して表示する。

正直、もっといい方法があると思いますが、
試行錯誤して実装・無事表示出来たので記録に残しておきます。

# 完成形

ここでは、いいねを**``「高評価」``**と設定しているので、高評価を用いて説明します。

* 質問に対する高評価と回答に対する高評価の合計を表示しています。
* 質問に対しては、高評価が2つあります。(👍が高評価数)
* 回答は、質問詳細に行くと1高評価となっています。

合計で、高評価数は3です。

![gif (10).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1029483/ab424b63-9e16-95b0-2f98-830aad3f95c9.gif)

# 前提
* devise機能実装済み。(member)
* 投稿機能実装済み。(question：ここでは質問)
* コメント機能実装済み(answer：ここでは回答)
* いいね機能実装済み(quesiton_like, answer_like：ここでは高評価)

いいねは、投稿とコメントの両方に出来るようにしてあります。

```ruby:schema.rb
ActiveRecord::Schema.define(version: 2021_05_05_122222) do
  create_table "answer_likes", force: :cascade do |t|
    t.integer "answer_id", null: false
    t.integer "member_id", null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["answer_id"], name: "index_answer_likes_on_answer_id"
    t.index ["member_id"], name: "index_answer_likes_on_member_id"
  end

  create_table "answers", force: :cascade do |t|
    t.integer "question_id", null: false
    t.integer "member_id", null: false
    t.text "content", null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["member_id"], name: "index_answers_on_member_id"
    t.index ["question_id"], name: "index_answers_on_question_id"
  end

  create_table "members", force: :cascade do |t|
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.string "confirmation_token"
    t.datetime "confirmed_at"
    t.datetime "confirmation_sent_at"
    t.string "unconfirmed_email"
    t.string "name", default: "", null: false
    t.text "introduction"
    t.string "image_id"
    t.string "country_code", default: "JP"
    t.string "experienced_country", default: ""
    t.boolean "is_deleted", default: false, null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["email"], name: "index_members_on_email", unique: true
    t.index ["reset_password_token"], name: "index_members_on_reset_password_token", unique: true
  end

  create_table "question_likes", force: :cascade do |t|
    t.integer "question_id", null: false
    t.integer "member_id", null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["member_id"], name: "index_question_likes_on_member_id"
    t.index ["question_id"], name: "index_question_likes_on_question_id"
  end

  create_table "questions", force: :cascade do |t|
    t.integer "member_id", null: false
    t.string "title", default: "", null: false
    t.text "content", null: false
    t.integer "best_answer_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["member_id"], name: "index_questions_on_member_id"
  end

```

# 手順

1. controllerへの記載　
2. viewへの記載

# 実装

###1. controllerへの記載　　

```ruby:controllers/members_controller.rb
def show
  @member = Member.find(params[:id])

  @member_questions = @member.questions
  @question_likes_count = 0
  @member_questions.each do |question|
    @question_likes_count += question.question_likes.size
  end

  @member_answers = @member.answers
  @answer_likes_count = 0
  @member_answers.each do |answer|
    @answer_likes_count += answer.answer_likes.size
  end

  @total_likes = @question_likes_count + @answer_likes_count

end
```

それぞれ説明します。

```ruby:質問に対する高評価を合計する
@member = Member.find(params[:id])

@member_questions = @member.questions
  @question_likes_count = 0
  @member_questions.each do |question|
    @question_likes_count += question.question_likes.size
  end
```

① ＠member_questionsには、@memberが投稿した投稿した全ての投稿が入ります。
② ＠question_likes_countには、初期値として0を設定します。ここに高評価が加算されていく仕組みです。
③ 最後に①の変数をeach文で繰り返し処理させます。each文の中にある下記の記述。

```ruby
@question_likes_count += question.question_likes.size
```
この文の意味は、下記の通りです。

```ruby
高評価の数(0) = 質問が持つ高評価の数 + 0
```

これが質問の数だけ繰り返されます。
つまり、繰り返される度に高評価の数(@question_likes_count)が増えていきます。
(0から、1へ。1から3へ。など、、、、、)

**``回答に対する高評価の合計も同様の記述で合計します。``**

その後、それぞれを合計する記述を書きます。

```ruby：回答に対する高評価を合計する
@total_likes = @question_likes_count + @answer_likes_count
```

これで、質問に対する高評価数と回答に対する高評価数を合計することができました。

###2. viewへの記載

最後に先ほど作成した変数をビューに記載するだけです。

```erb:views/members/show.html.erb
<div class="text-center w-100">
  <p class="small border border-primary rounded">高評価数</p>
  <h5><%= @total_likes %></h5>
</div>
```

@total_likesには、@memberが既に組み込まれているため、 **``@member.``**の記述がなくても動きます・

以上です。


気になるあれば、コメントでもいただけると幸いです。