0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Rails 閲覧数 カウント

Last updated at Posted at 2023-07-03

はじめに

  • 投稿詳細ページの閲覧数をカウントし、投稿一覧と投稿詳細に表示させる
  • 学習内容の備忘録です

前提条件

  • ユーザーと投稿に関する機能が実装できている
  • ここでは、UsersテーブルとBooksテーブルがある状態
  • Bootstrap4を入れている状態

手順

  1. モデル作成
  2. アソシエーション
  3. コントローラ
  4. ビュー

1.モデル作成

今回作成するモデルはLookモデルとします。

ターミナル
rails g model Look user_id:integer book_id:integer

migrationファイルを確認し、問題なければ、

ターミナル
rails db:migrate

2.アソシエーション

look.rb
belongs_to :user
belongs_to :book
validates_uniqueness_of :book_id, scope: :user_id

補足
「validates_uniqueness_of :book_id, scope: :user_id」によって、同じ本(book_id)に対して同じ人(user_id)の閲覧カウントが重複しないようにしている。

book.rb
has_many :looks, dependent: :destroy
user.rb
has_many :looks, dependent: :destroy

1人のユーザーは複数の閲覧データを持ち、1冊の本も複数の閲覧データを持つ。

user:book=N:N
user:look=1:N
book:look=1:N

のアソシエーションが完成!

3.コントローラー

ここでは、booksコントローラーに閲覧数をカウントさせる記述を書く。
(bookの閲覧数なので、looksコントローラーは作成しない)

books_contoroller.rb
def show

    #省略

    # ゲストユーザーログインを実装しているため、ゲストユーザーでない時に限定
    if current_user.name != "guestuser"

      # Lookの中にbook_idとユーザーのidが一致するものがないか探し、unlessによって、falseの場合のみ実行する
      unless Look.find_by(user_id: current_user.id, book_id: @book.id)

        # このユーザーのlooksを新たに作成し、book_idに取得してきた本のidを入力
        current_user.looks.create(book_id: @book.id)

      end
    end
  end

補足
今回は1人1カウントにしたが、1日1カウントにしたい場合は、
「where(created_at: Time.zone.now.all_day)」で、可能になる。

参考にさせていただきました

[Rails]ページの閲覧数をカウントする方法

4.ビュー

今回は、閲覧数をカウントし表示する記述は、部分テンプレートにまとめた。

_look.html.erb
# user_has_look?メソッドはbookモデルに定義する
<% if current_user && book.user_has_look?(current_user) %>
  <div class="text-danger"> # 閲覧した場合は、赤色に
    閲覧数:<%= book.looks.count %>
  </div>
<% else %>
  <div class="text-dark"> # 閲覧していない場合は、黒色に
    閲覧数<%= book.looks.count %>
  </div>
<% end %>

user_has_look?メソッドの定義をしておく

book.rb
# userを引数にし、user_idにこのユーザーのidが存在するかを確認する
def user_has_look?(user)
  looks.where(user_id: user.id).exists?
end

あとは、この部分テンプレートを呼び出したいところへ!
(ここでは、本の一覧表示についても部分テンプレートに記述している。)

_index.html.erb
# 省略
<% books.each do |book| %>
# 省略

# 閲覧数を表示したい部分に記述
<%= render partial: "books/look", locals: { book: book } %>

詳細ページにも!

show.html.erb
# 閲覧数を表示したい部分に記述
<%= render partial: "books/look", locals: { book: @book } %>

まとめ

  • 閲覧カウントは、ユーザーと投稿に中間テーブルを設ける
  • 投稿に関するコントローラーでidを作成する

⚠️学習4ヶ月目の初学者による投稿です。
⚠️間違いがあるかもしれません。ご容赦ください。
⚠️ご指導、ご教授いただけると幸いです。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?