我找到了几个解决这个问题的方法,比如这篇文章中的railstat:
我有一堆文章和评论,我想要一个由唯一IP过滤的点击计数器。完全像Stackoverflow为这篇文章做的。但是当谷歌分析已经为我做这个并且包括大量代码,跟踪独特的IP等时,我并不真正关心像railstat这样的解决方案。我现在的想法是使用Garb或其他一些分析插件可以提取页面统计数据,如果它们比12小时更新某些表格更早,但我还需要一个cache_column。
我假设您可以从Google Analytics中为特定页面提取统计信息,并且每12小时更新一次统计信息?
我想知道为什么这会是一个坏主意,或者有人有更好的解决方案?
由于
答案 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