🫧

Rails 閲覧数の表示

2023/04/23に公開

閲覧数の表示

  • ページの閲覧数をカウントし、投稿一覧、投稿詳細に表示させる
    ※ 閲覧数は、各投稿へアクセスした数を集計

こちらの記事を参照しました!
https://qiita.com/Auk10/items/6c789a569bfe71214745

ER図

bookとuserと1対Nの関係になる「閲覧数」モデルを作成

各bookのshowページにアクセスした時に
book_idとuser_idをViewCountに登録する。

閲覧数の表示のために
該当するbookを探す(Book.find(params[:id])など)
アソシエーションを用いて該当するbook_idを持つViewCountのデータを数える

モデルの作成

rails g model ReadCount user_id:integer book_id:integer

referencesで書く場合

rails g model ReadCount user:references book:references

referencesとは

モデル作成時に references を使うことで、他のテーブルへの外部キーを設定することができる!!

userモデルとbookモデルにはhas_many :view_countsメソッドが追加され、ViewCountモデルには、belongs_to :user、belongs_to :bookが追加される!🙆🏻‍♀️

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

rails db:migrate

(references型なら入力済みの筈ですが、)

アソシエーションの設定

1人のユーザーは複数の閲覧データを持つ
user : view_count = 1 : N
1つの本は複数の閲覧データを持つ
book : view_count = 1 : N

user.rb

has_many :read_counts, dependent: :destroy

book.rb

has_many :read_counts, dependent: :destroy

view_count.rb

belongs_to :user
belongs_to :book

contorollerへの記述

今回はBookの閲覧数なので、新しくcontorollerは作成する必要はない。

def show
    @book_detail = Book.find(params[:id])
    unless ViewCount.find_by(user_id: current_user.id, book_id: @book_detail.id)
      current_user.view_counts.create(book_id: @book_detail.id)
    end
  end

一度閲覧したユーザーを数えたくないので

ViewCount.find_by(user_id: current_user.id, book_id: @book_detail.id)

でViewCountの中に、取得したbook_idとuser_idが一致するものが無いかを探して、
合致するものがなかった場合(falseの場合)に下記を実行するという処理で実装している!

current_user.view_counts.create(book_id: @book_detail.id)

このコードは、current_userが、書籍の詳細ページを訪れたことを記録するための記述。

current_userが所有するview_countsに対して、新しいViewCountオブジェクトを作成して保存している!そこに、book_idという属性が設定され、current_userがどの書籍の詳細ページを訪れたかが記録されるということ。

閲覧数のカウントを1つの投稿に付き1人の1日1回まで数える方法

class BooksController < ApplicationController
 def show
    @book = Book.find(params[:id])
    unless ViewCount.where(created_at: Time.zone.now.all_day).find_by(user_id: current_user.id, book_id: @book.id)
      current_user.read_counts.create(book_id: @book.id)
    end
 end
end

where(created_at: Time.zone.now.all_day)
で、今日作成されたReadCountのデータを抽出、

.find_by(user_id: current_user.id, book_id: @book.id)
Book.findで取得したbook_idとユーザーのidが一致するものが無いかを探す。

この処理を組み合わせればOK!

viewページ

必要な箇所に追記する!

<td>閲覧数: <%= book.view_counts.count %></td>

book.view_countsは、bookオブジェクトに関連付けられたview_countsのコレクションを返し、.countは、このコレクション内の要素の数を返す。
なので、本の閲覧数をカウントして表示することができる!


課題a完成!
今回はER図を手書きではなく、きちんとツールを使って書いてみた!🙆🏻‍♀️
できることが増えてきてるのと、自分のペースで勉強できているのが楽しい!

Discussion