用于rails中页面视图的简单计数器

时间:2011-01-27 11:26:10

标签: ruby-on-rails ruby-on-rails-3 google-analytics google-api counter

我找到了几个解决这个问题的方法,比如这篇文章中的railstat:

Page views in Rails

我有一堆文章和评论,我想要一个由唯一IP过滤的点击计数器。完全像Stackoverflow为这篇文章做的。但是当谷歌分析已经为我做这个并且包括大量代码,跟踪独特的IP等时,我并不真正关心像railstat这样的解决方案。我现在的想法是使用Garb或其他一些分析插件可以提取页面统计数据,如果它们比12小时更新某​​些表格更早,但我还需要一个cache_column。

我假设您可以从Google Analytics中为特定页面提取统计信息,并且每12小时更新一次统计信息?

我想知道为什么这会是一个坏主意,或者有人有更好的解决方案?

由于

1 个答案:

答案 0 :(得分:94)

<强>更新

此答案中的代码用作http://github.com/charlotte-ruby/impressionist的基础 试一试


这可能会花费您更少的时间将其编码到您的应用中,然后它会使用他们的API从Google Analytics中提取数据。这些数据很可能更准确,您不必依赖外部依赖性。您也可以实时获取统计数据,而不是等待12小时的Google Analytics数据。 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

在关联的文章模型中添加一行,并添加一个返回展示次数的方法:

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 action上为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

<%=@article.unique_impression_count %>

如果您在一堆型号上使用它,您可能想要干它。将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中的模块。您可以将send include放在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