在rails中的页面视图的简单点击计数器。

时间:2021-10-07 13:52:39

I've found several solutions for this problem, for example railstat from this post:

我为这个问题找到了几个解决方案,例如来自本文的railstat:

Page views in Rails

页面浏览量在Rails中

I have a bunch of articles and reviews which I would like a hit counter filtered by unique IPs. Exactly like * does for this post. But I don't really care for such a solution as railstat when google analytics is already doing this for me and including a whole lot of code, keeping track of unique IPs, etc.. My present thinking is to use Garb or some other Analytics plugin to pull the pages stats if they are older than say 12 hours updating some table, but I also need a cache_column.

我有一堆文章和评论,我想要一个被独特的ip过滤掉的计数器。就像*对这个帖子所做的一样。但是我并不喜欢railstat这样的解决方案,因为谷歌analytics已经在为我做这个了,并且包含了大量的代码,跟踪唯一的ip等等。我目前的想法是,如果页面更新时间超过12小时,那么就使用Garb或其他分析插件来提取页面统计数据,但我还需要一个cache_column。

I'm assuming you can pull stats from Analytics for a particular page and that they update their stats every 12 hours?

我假设你可以从一个特定页面的分析中提取统计数据,他们每12小时更新一次统计数据?

I'm wondering if there are any reasons why this would be a bad idea, or if someone has a better solution?

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

Thanks

谢谢

1 个解决方案

#1


93  

UPDATE

更新

The code in this answer was used as a basis for http://github.com/charlotte-ruby/impressionist Try it out

这个答案中的代码被用作http://github.com/charlotte- ruby/印象派尝试它的基础


It would probably take you less time to code this into your app then it would to pull the data from Analytics using their API. This data would most likely be more accurate and you would not have to rely an an external dependancy.. also you would have the stats in realtime instead of waiting 12 hours on Analytics data. request.remote_ip works pretty well. Here is a solution using polymorphism. Please note that this code is untested, but it should be close.

你可能需要更少的时间将这些代码编码到你的应用中,然后它就会使用他们的API从分析中提取数据。这些数据很可能更准确,你不必依赖外部依赖。你也可以实时获取数据,而不是在分析数据上等待12个小时。请求。remote_ip工作得很好。这是一个使用多态性的解决方案。请注意,这段代码没有经过测试,但是应该是接近的。

Create a new model/migration to store your page views (impressions):

创建一个新的模型/迁移来存储您的页面视图(印象):

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

Add a line to your Article model for the association and add a method to return the impression count:

在您的文章模型中添加一行用于关联,并添加一个方法来返回印象计数:

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

Create a before_filter for articles_controller on the show action:

在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

Then you just call the unique_impression_count in your view

然后在视图中调用unique_印象性_count

<%=@article.unique_impression_count %>

If you are using this on a bunch of models, you may want to DRY it up. Put the before_filter def in application_controller and use something dynamic like:

如果你在很多模型上使用这个,你可能想把它弄干。将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)

And also move the code in the Article model to a module that will be included in ActiveRecord::Base. You could put the send include in a config/initializer.. or if you want to get crazy, just turn the whole thing into a rails engine, so you can reuse on other apps.

并将文章模型中的代码移动到ActiveRecord: Base中包含的模块中。您可以将send include放在配置/初始化器中。或者,如果你想疯掉,那就把整个东西变成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

#1


93  

UPDATE

更新

The code in this answer was used as a basis for http://github.com/charlotte-ruby/impressionist Try it out

这个答案中的代码被用作http://github.com/charlotte- ruby/印象派尝试它的基础


It would probably take you less time to code this into your app then it would to pull the data from Analytics using their API. This data would most likely be more accurate and you would not have to rely an an external dependancy.. also you would have the stats in realtime instead of waiting 12 hours on Analytics data. request.remote_ip works pretty well. Here is a solution using polymorphism. Please note that this code is untested, but it should be close.

你可能需要更少的时间将这些代码编码到你的应用中,然后它就会使用他们的API从分析中提取数据。这些数据很可能更准确,你不必依赖外部依赖。你也可以实时获取数据,而不是在分析数据上等待12个小时。请求。remote_ip工作得很好。这是一个使用多态性的解决方案。请注意,这段代码没有经过测试,但是应该是接近的。

Create a new model/migration to store your page views (impressions):

创建一个新的模型/迁移来存储您的页面视图(印象):

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

Add a line to your Article model for the association and add a method to return the impression count:

在您的文章模型中添加一行用于关联,并添加一个方法来返回印象计数:

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

Create a before_filter for articles_controller on the show action:

在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

Then you just call the unique_impression_count in your view

然后在视图中调用unique_印象性_count

<%=@article.unique_impression_count %>

If you are using this on a bunch of models, you may want to DRY it up. Put the before_filter def in application_controller and use something dynamic like:

如果你在很多模型上使用这个,你可能想把它弄干。将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)

And also move the code in the Article model to a module that will be included in ActiveRecord::Base. You could put the send include in a config/initializer.. or if you want to get crazy, just turn the whole thing into a rails engine, so you can reuse on other apps.

并将文章模型中的代码移动到ActiveRecord: Base中包含的模块中。您可以将send include放在配置/初始化器中。或者,如果你想疯掉,那就把整个东西变成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