【Rails】アクセス数をカウントしたかったので、impressionistを導入

初めに

ブログを作成していたので、記事にアクセスした回数を確認したく、探してみたところimpressionistというgemを発見。
少しつまづいたのと、まだ仮実装ですが、見返せるように投稿しておきます。

開発環境

バージョン
Ruby 2.5.1
Rails 5.2.3
impressionist 1.6.1

impressionistのバージョンはRails5なら1.6.1でないとエラーが出るようです。

やり方

ざっくりとですが、カラムを作ったり、モデルにコードを書いたりします。
カウントしたい対象のテーブルにimpressions_countというカラムをintegerで作ります。

下記はあくまで例です。

class CreateUsers < ActiveRecord::Migration[5.1]
  def change
    create_table :users do |t|
      t.string :name
      t.integer :impressions_count, default: 0
 
      t.timestamps
    end
  end
end

gemをインストールしましょう。
gem

gem 'impressionist'

$ bundle install してimpressionistをgenerateします。
ターミナル

$ rails g impressionist
Running via Spring preloader in process 134476
      invoke  active_record
      create    db/migrate/20180804231718_create_impressions_table.rb
      create  config/initializers/impression.rb

マイグレーションは下記が出来上がります。
migration.rb

class CreateImpressionsTable < ActiveRecord::Migration[5.1]
  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

migrationしましょう。
ターミナル

$ rails db:migrate

モデルに:counter_cacheを設定

class User < ApplicationRecord
    is_impressionable counter_cache: true
end

コントローラーに以下設定

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

今回はuserとしてますが、記事とかであればarticleでもいいですし、動画ならvideoとかですかね?
また、:unique => [:session_hash]は自分の場合一旦消しました。
おそらくこれが無いと、同一のユーザーがアクセスした分カウントされてしまうのだと思われます。
ですが、TypeError - can't quote Rack::Session::SessionIdといったエラーが出てしまい、一旦カウントができる状態で仮完了としました。
エラーの参考記事はこちらです。

ruby on rails - TypeError - can't quote Rack::Session::SessionId - Stack Overflow
あとはViewで呼び出せばOKです。

<%= @user.impressions_count %>

このあとランキングを作ろうと思ってます。

参考

https://remonote.jp/rails-impressionist-ranking

https://github.com/charlotte-ruby/impressionist