この問題のいくつかの解決策を見つけました。たとえば、この投稿のrailstatです。
独自のIPでフィルターされたヒットカウンターが欲しい記事やレビューがたくさんあります。 Stackoverflowがこの投稿に対して行うのとまったく同じです。しかし、Googleアナリティクスがすでにこれを実行していて、大量のコードを含めたり、一意のIPを追跡したりしている場合、私はrailstatのようなソリューションにはあまり関心がありません。私の現在の考えはGarbまたは他のアナリティクスを使用することですプラグインを使用して、ページが12時間以上経過している場合にページの統計情報をプルしますが、cache_columnも必要です。
Analyticsから特定のページの統計情報を取得でき、それらが12時間ごとに統計情報を更新すると想定していますか?
これが悪い考えになる理由があるのか、誰かがより良い解決策を持っているのだろうか?
ありがとう
[〜#〜]更新[〜#〜]
この回答のコードは http://github.com/charlotte-Ruby/impressionist の基礎として使用されました
これをアプリにコード化する時間は、APIを使用してAnalyticsからデータを取得するよりも時間がかかりません。このデータはより正確である可能性が高く、外部の依存関係に依存する必要はありません。また、Analyticsデータで12時間待機する代わりに、リアルタイムで統計を取得できます。 request.remote_ip
はかなりうまくいきます。以下は、ポリモーフィズムを使用したソリューションです。このコードはテストされていませんが、近いはずです。
新しいモデル/マイグレーションを作成して、ページビュー(インプレッション)を保存します。
class Impressions < ActiveRecord::Base
belongs_to :impressionable, :polymorphic=>true
end
class CreateImpressionsTable < ActiveRecord::Migration
def self.up
create_table :impressions, :force => true do |t|
t.string :impressionable_type
t.integer :impressionable_id
t.integer :user_id
t.string :ip_address
t.timestamps
end
end
def self.down
drop_table :impressions
end
end
関連のArticleモデルに行を追加し、インプレッション数を返すメソッドを追加します。
class Article < ActiveRecord::Base
has_many :impressions, :as=>:impressionable
def impression_count
impressions.size
end
def unique_impression_count
# impressions.group(:ip_address).size gives => {'127.0.0.1'=>9, '0.0.0.0'=>1}
# so getting keys from the hash and calculating the number of keys
impressions.group(:ip_address).size.keys.length #TESTED
end
end
Showアクションで、articles_controllerのbefore_filterを作成します。
before_filter :log_impression, :only=> [:show]
def log_impression
@article = Article.find(params[:id])
# this assumes you have a current_user method in your authentication system
@article.impressions.create(ip_address: request.remote_ip,user_id:current_user.id)
end
次に、ビューでunique_impression_countを呼び出すだけです
<%[email protected]_impression_count %>
これを一連のモデルで使用している場合は、DRY it up。before_filter defをapplication_controllerに入れて、次のような動的なものを使用します。
impressionable_class = controller_name.gsub("Controller","").constantize
impressionable_instance = impressionable_class.find(params[:id])
impressionable_instance.impressions.create(ip_address:request.remote_ip,user_id:current_user.id)
また、ArticleモデルのコードをActiveRecord :: Baseに含まれるモジュールに移動します。送信インクルードをconfig/initializerに追加することもできます。または、気が狂ったら、すべてをRailsエンジンに変更して、他のアプリで再利用できるようにします。
module Impressionable
def is_impressionable
has_many :impressions, :as=>:impressionable
include InstanceMethods
end
module InstanceMethods
def impression_count
impressions.size
end
def unique_impression_count
impressions.group(:ip_address).size
end
end
end
ActiveRecord::Base.extend Impressionable