ひーろのアウトプットブログ

プログラミングの学習記録と開発日記です

impressionistを使ってPV数を計測する

制作中のアプリにPV数をカウントする機能が欲しかったので調べてみたところ、impressionistというgemが良さそうだったので導入してみました。

前提

ruby: 2.6.6
rails: 6.0.6.5

導入

いつものようにGemfileへgemを記述しinstallします。

gem 'impressionist'
$ bundle install

これで導入できた…と思ったんですが、後になってエラーが起こりました。
どうやらimpressionistの最新版にはバグがあるようなので、安定版を使います。
参考に記載のある記事を元に次のように記述します。

gem 'impressionist',
    git: 'git://github.com/charlotte-ruby/impressionist.git',
    ref: '46a582ff8cd3496da64f174b30b91f9d97e86643'
$ bundle install

これでOKです。

次にテーブルを作成します。

$ rails g impressionist

このコマンドでマイグレーションファイルが作られます。
一応中身を確認してみると、

  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

この様になってるかと思います。
そのままmigrateします。

$ rails db:migrate

PV数を計測したいページのテーブルにカラムを追加します。
今回はUsersのshowページに付けることにしてみます。
まずはmigrationファイルを作成します。

$ railg g migration AddImpressionsCountToUsers impressions_count:integer

作成したmigrationファイルにdefaultの値を追記します。

class AddImpressionsCountToUsers < ActiveRecord::Migration[5.2]
  def change
  # default: 0 初期値を0とする
    add_column :users, :impressions_count, :integer, default: 0
  end
end

再びmigrateします。

rails db:migrate

一度サーバーを再起動してimpressionistのメソッドを使えるようにしておきます。

コントローラの設定

Userの詳細ページを閲覧した際にPVを計測したいので、showアクションに記述していきます。
同一の閲覧者がページをリロードし3回見た時PVのカウントを3とすると正確性が落ちるので、session_hashを使用して1回だけカウントされるようにします。

def show
  impressionist(@user, nil, unique: [:session_hash])
  @user = User.find(params[:id])
end

モデルの設定

counter_cacheオプションを付けて記述します。

class User < ActiveRecord::Base
  is_impressionable counter_cache: true
end

ビューで表示する

これでPV数計測の準備が整いました。 実際にshowページで見てみましょう。

= @user.impressions_count

先ほど追加したカラムを使い表示すると、「1」という数字が出てくるはずです。
これは自分がアクセスした数が表示されていて、PV数の計測が成功していることがわかります。
以上で実装ができました。アプリを実際にデプロイしたら、ユニークユーザーがアクセスしてくれる度にPV数が1ずつ増えていきます。

参考

https://github.com/charlotte-ruby/impressionist https://remonote.jp/rails-impressionist-ranking https://qiita.com/yimajo/items/995584ede90be1a873ce

https://www.autovice.jp/articles/108?tag_id=1 *6/24追記