#実装すること
- gem impressionistを使用して、投稿ページにPV(ページビュー)を設置します。
- 同じユーザーがPV数を稼ぐ、増やせないように同じセッションはカウントしないようにします。
impressionist: https://github.com/charlotte-ruby/impressionist
こちらのgithubを参考に実装していきます。
#完成形
目のアイコンがPV数を表示しており、
投稿詳細に行くと数字がカウントされています。
#前提
下記の機能実装済み。
・devise(今回は、memberモデル)
・投稿機能(今回は、questionモデル)
ActiveRecord::Schema.define(version: 2021_05_05_122222) do
create_table "members", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.datetime "remember_created_at"
t.string "name", default: "", null: false
t.text "introduction"
t.string "image_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["email"], name: "index_members_on_email", unique: true"index_members_on_reset_password_token", unique: true
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.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["member_id"], name: "index_questions_on_member_id"
end
end
#手順
①gem"impressionist"の導入
②modelへの記載
③controllerへの記載
④viewへの記載
#実装
###1. impressionistのインストール
railsのバージョンに注意。(6と5以下で異なる)
私は5なので、下記を記載。
#rails 5 or lower
gem 'impressionist', '~>1.6.1'
インストールします。
bundle install
impressionistのマイグレーションファイルを作成します。
rails g impressionist
下記が自動的に作成されます。
*user_idとありますが、ここは特にいじる必要はありません。
私はuserではなく、memberを使用していたのでmember_idに修正したところエラーが出ました。
私自身が作成したmemberモデルを表すidではなかったです。
class CreateImpressionsTable < ActiveRecord::Migration[5.2]
def self.up
create_table :impressions, :force => true do |t|
t.string :impressionable_type
t.integer :impressionable_id
t.integer :user_id
t.string :controller_name
t.string :action_name
t.string :view_name
t.string :request_hash
t.string :ip_address
t.string :session_hash
t.text :message
t.text :referrer
t.text :params
t.timestamps
end
add_index :impressions, [:impressionable_type, :message, :impressionable_id], :name => "impressionable_type_message_index", :unique => false, :length => {:message => 255 }
add_index :impressions, [:impressionable_type, :impressionable_id, :request_hash], :name => "poly_request_index", :unique => false
add_index :impressions, [:impressionable_type, :impressionable_id, :ip_address], :name => "poly_ip_index", :unique => false
add_index :impressions, [:impressionable_type, :impressionable_id, :session_hash], :name => "poly_session_index", :unique => false
add_index :impressions, [:controller_name,:action_name,:request_hash], :name => "controlleraction_request_index", :unique => false
add_index :impressions, [:controller_name,:action_name,:ip_address], :name => "controlleraction_ip_index", :unique => false
add_index :impressions, [:controller_name,:action_name,:session_hash], :name => "controlleraction_session_index", :unique => false
add_index :impressions, [:impressionable_type, :impressionable_id, :params], :name => "poly_params_request_index", :unique => false, :length => {:params => 255 }
add_index :impressions, :user_id
end
def self.down
drop_table :impressions
end
end
dbに反映させましょう。
rails db:migrate
###2. modelへの記載
class Question < ApplicationRecord
is_impressionable
belongs_to :member
validates :title, presence: true
validates :title, length: { minimum: 5, maximum: 50 }, allow_blank: true
validates :content, presence: true
validates :content, length: { minimum: 20 }, allow_blank: true
end
下記を一番上に追加しています。
is_impressionable
or
is_impressionable :counter_cache => true
これを追加することで、questionモデルでimpresionistを使う事ができます。
###3. controllerへの記載
class Public::QuestionsController < ApplicationController
impressionist :actions => [:show]
def show
@member = current_member
@question = Question.find(params[:id])
impressionist(@question, nil, unique: [:session_hash.to_s])
end
それぞれ説明します。
impressionist :actions => [:show]
⇨ PV数を計測したいので、アクションを指定します。
・投稿詳細(questions#show)で計測したい。
・[ ]内は、計測したいアクションを記載。
impressionist(@question, nil, unique: [:session_hash.to_s])
⇨ showアクション内にも記載します。
・@questionを計測する対象として設定します。
今回は、投稿詳細なので@question。showにある変数を入れましょう。
・uniqueでは、どの値で計測するかを書きましょう。今回は、sessionで計測したいので、
先ほど作成した、マイグレーションファイルのカラム名を書きましょう。(参照: t.string :session_hash)
###4.viewへの記載
*わかりやすくするために余計な箇所は省いてあります。
<div class="container">
<div class= "row">
<div class="col-md-3 pt-5">
<i class="fas fa-eye">
<%= @question.impressionist_count(:filter=>:session_hash) %>
</i>
</div>
</div>
</div>
ここで計測(いわゆるcount)したいので、下記を記載します。
<%= @question.impressionist_count(:filter=>:session_hash) %>
・ impressionist_countで計測。
・ (:filter=>:session_hash)でフィルターをかけ、どれで計測するか設定。
今回は、sessionで計測なので、記載の通り。
これで問題なく計測できるかと思います。
もし、エラーや上手く動かない。などあればコメント頂けたらと思います。
以上です。