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

hol*_*den 37 counter google-analytics ruby-on-rails google-api ruby-on-rails-3

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

Rails中的页面视图

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

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

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

谢谢

joh*_*ley 93

UPDATE

这个答案中的代码被用作http://github.com/charlotte-ruby/impressionist的基础 试试看


这可能会花费您更少的时间将其编码到您的应用中,然后它会使用他们的API从Google 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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

在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
Run Code Online (Sandbox Code Playgroud)

然后,您只需在视图中调用unique_impression_count即可

<%=@article.unique_impression_count %>
Run Code Online (Sandbox Code Playgroud)

如果你在一堆模型上使用它,你可能想要干它.将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)
Run Code Online (Sandbox Code Playgroud)

并且还将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
Run Code Online (Sandbox Code Playgroud)

  • 我为此创建了一个插件:https://github.com/charlotte-ruby/impressionist (22认同)
  • 在`after_filter`中记录印象会不会更有意义?这样您就可以避免与计划执行的其他过滤器发生任何冲突,例如友好的id gem.此外,如果任何用户授权将用户重定向到其他位置(如果他们没有足够的页面权限),则可以避免记录展示.编辑:哇,de-ja-vu,看起来我已经打开了这张https://github.com/charlotte-ruby/impressionist/issues/50的门票 (3认同)