Rails 閲覧数の表示
閲覧数の表示
- ページの閲覧数をカウントし、投稿一覧、投稿詳細に表示させる
※ 閲覧数は、各投稿へアクセスした数を集計
こちらの記事を参照しました!
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